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 (),