This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch] Partial fix for libstdc++/15002


Hi,

curious: I was already working on this issue when PR 15002 was submitted.

Anyway, this is a partial fix, a simple good improvement. For the testcase
presented - reading 200000 lines each one 200 chars long - with

   std::ifstream f("test.file");
   std::string l;
   while (std::getline(f, l));

on my P4-2400, -O2:

3.3.3
-----
5.130u 0.020s 0:05.15 100.0%    0+0k 0+0io 211pf+0w

mainline/3.4.0
--------------
3.000u 0.060s 0:03.06 100.0%    0+0k 0+0io 203pf+0w

patched
-------
1.140u 0.040s 0:01.19 99.1%     0+0k 0+0io 205pf+0w

The fix is not complete, we can do better, but rather general: I noticed
in the profile that we were spending most of the time in memset, whereas
for all the single char modifying algorithms we had better just assigning
the char. All the single char modifying algorithms take advantage of this
tweak, for instance performance/21_strings/string_append.cc becomes about
2.5 times faster.

Tested x86-linux.

Paolo.

/////////////////////
2004-04-18  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/15002 (partial)
	* include/bits/basic_string.h (_M_replace_aux, _M_replace_safe):
	Special case __n2 == 1, not calling traits_type::assign/copy. 
diff -urN libstdc++-v3-orig/include/bits/basic_string.h libstdc++-v3/include/bits/basic_string.h
--- libstdc++-v3-orig/include/bits/basic_string.h	2004-02-27 01:49:49.000000000 +0100
+++ libstdc++-v3/include/bits/basic_string.h	2004-04-18 16:19:44.000000000 +0200
@@ -1342,7 +1342,9 @@
 	if (this->max_size() - (this->size() - __n1) < __n2)
 	  __throw_length_error(__N("basic_string::_M_replace_aux"));
 	_M_mutate(__pos1, __n1, __n2);
-	if (__n2)
+	if (__n2 == 1)
+	  _M_data()[__pos1] = __c;
+	else if (__n2)
 	  traits_type::assign(_M_data() + __pos1, __n2, __c);
 	return *this;
       }
@@ -1352,7 +1354,9 @@
 		      size_type __n2)
       {
 	_M_mutate(__pos1, __n1, __n2);
-	if (__n2)
+	if (__n2 == 1)
+	  _M_data()[__pos1] = *__s;
+	else if (__n2)
 	  traits_type::copy(_M_data() + __pos1, __s, __n2);
 	return *this;
       }
@@ -1960,7 +1964,7 @@
    *  @param rhs  Last string.
    *  @return  New string with value of @a lhs followed by @a rhs.
    */
- template<typename _CharT, typename _Traits, typename _Alloc>
+  template<typename _CharT, typename _Traits, typename _Alloc>
     basic_string<_CharT, _Traits, _Alloc>
     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
 	      const basic_string<_CharT, _Traits, _Alloc>& __rhs)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]