Hi,

I have been working on a fix for STDCXX-493. The attached patch tries to
improve both the const_pointer and string overloads but makes no attempt
to do anything with the value_type overload. I was successful in making
the const_pointer overload run faster (about 6 times faster than in the
submitted test), but for some reason the patch doesn't help the string
overload. I'm fresh out of ideas at the moment and would welcome help
with it.

$ let n=0; while [ $n -lt 3 ]; do time ./append-stdcxx-patched 500000000 $n; let n=`expr $n + 1`; done
std::string::append(size_type, value_type)

real    0m11.198s
user    0m10.109s
sys     0m1.036s
std::string::append(const_pointer)

real    0m2.934s
user    0m1.720s
sys     0m1.208s
std::string::append(const std::string&)

real    0m7.886s
user    0m6.724s
sys     0m1.132s

$ let n=0; while [ $n -lt 3 ]; do time LD_LIBRARY_PATH=../lib ./append-stdcxx-4.1.3 500000000 $n; let n=`expr $n + 1`; done
std::string::append(size_type, value_type)

real    0m10.425s
user    0m9.301s
sys     0m1.128s
std::string::append(const_pointer)

real    0m12.965s
user    0m11.829s
sys     0m1.132s
std::string::append(const std::string&)

real    0m8.017s
user    0m6.832s
sys     0m1.184s

$ let n=0; while [ $n -lt 3 ]; do time ./append-gcc-4.1.2 500000000 $n; let n=`expr $n + 1`; done
std::string::append(size_type, value_type)

real    0m4.369s
user    0m3.764s
sys     0m0.604s
std::string::append(const_pointer)

real    0m4.551s
user    0m3.884s
sys     0m0.668s
std::string::append(const std::string&)

real    0m5.097s
user    0m4.412s
sys     0m0.684s

-- Mark
Index: /home/mbrown/stdcxx/include/string
===================================================================
--- /home/mbrown/stdcxx/include/string	(revision 558531)
+++ /home/mbrown/stdcxx/include/string	(working copy)
@@ -294,14 +294,14 @@
 
     basic_string& append (const basic_string&, size_type, size_type);
 
-    basic_string& append (const basic_string&);
-
-    basic_string& append (const_pointer __s, size_type __n) {
-        return replace (size (), size_type (), __s, __n);
+    basic_string& append (const basic_string &__str) {
+        return append (__str.data (), __str.size ());
     }
 
+    basic_string& append (const_pointer, size_type);
+
     basic_string& append (const_pointer __s) {
-        return replace (size (), size_type (), __s);
+        return append (__s, traits_type::length (__s));
     }
 
 #ifndef _RWSTD_NO_MEMBER_TEMPLATES
@@ -1178,16 +1178,17 @@
 template <class _CharT, class _Traits, class _Allocator>
 inline basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::
-append (const basic_string &__str)
+append (const_pointer __s, size_type __n)
 {
-    const size_type __size = size () + __str.size ();
+    const size_type __newsize = size () + __n;
 
-    if (   capacity () < __size
+    if (   capacity () <= __newsize
         || size_type (1) < size_type (_C_pref ()->_C_get_ref ()))
-        return append (__str, size_type (), __str.size ());
+        return replace (size (), size_type (), __s, __n);
 
-    traits_type::copy (_C_data + size (), __str.data (), __str.size () + 1);
-    _C_pref ()->_C_size._C_size = __size;
+    traits_type::copy (_C_data + size (), __s, __n);
+    traits_type::assign (_C_data [__newsize], value_type ());
+    _C_pref ()->_C_size._C_size = __newsize;
 
     return *this;
 }

Reply via email to