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;
}