mark.g.brown wrote:
Hi all,

The attached simple patch speeds up push_back() nearly six times
relative to stdcxx 4.1.3 and makes it more than twice faster that
gcc's.

Wow, that's a pretty impressive improvement! Thanks for the patch!
It makes sense to optimize this case instead of being lazy and
calling a more general out-of-line function. We should review the
rest of string (and other containers) for similar opportunities.
Let me test your patch for regressions and if it passes I'll
commit it tomorrow.

Martin


$ time ./push_back-stdcxx-patched 500000000

real    0m2.800s
user    0m1.676s
sys     0m1.084s

$ time ./push_back-stdcxx-4.1.3 500000000

real    0m11.206s
user    0m10.017s
sys     0m1.184s

$ time ./push_back-gcc 500000000

real    0m4.555s
user    0m3.840s
sys     0m0.716s


--Mark


------------------------------------------------------------------------

Index: /home/mbrown/stdcxx/include/string
===================================================================
--- /home/mbrown/stdcxx/include/string  (revision 558531)
+++ /home/mbrown/stdcxx/include/string  (working copy)
@@ -340,9 +340,7 @@
     }
// lwg issue 7
-    void push_back (value_type __c) {
-        append (size_type (1), __c);
-    }
+    void push_back (value_type);
basic_string& assign (const basic_string &__str) {
         return *this = __str;
@@ -1088,6 +1086,22 @@
template <class _CharT, class _Traits , class _Allocator>
 inline void basic_string<_CharT, _Traits, _Allocator>::
+push_back (value_type __c)
+{
+    const size_type __size = size () + 1;
+
+    if (   capacity () < __size
+        || size_type (1) < size_type (_C_pref ()->_C_get_ref ()))
+        append (1, __c);
+    else {
+        traits_type::assign (_C_data [size ()], __c);
+        _C_pref ()->_C_size._C_size = __size;
+    }
+}
+
+
+template <class _CharT, class _Traits , class _Allocator>
+inline void basic_string<_CharT, _Traits, _Allocator>::
 reserve (size_type __cap)
 {
     _RWSTD_REQUIRES (__cap <= max_size (),

Reply via email to