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] Fix libstdc++/15002 (continued)


Hi Pétur, hi all,

the below implements your suggestion. This is what I get here,
performance-wise:

current mainline
----------------
0.970u 0.100s 0:01.06 100.9%    0+0k 0+0io 201pf+0w

old tentative patch using sungetc()
-----------------------------------
0.600u 0.090s 0:00.69 100.0%    0+0k 0+0io 202pf+0w

this patch
----------
0.210u 0.100s 0:00.31 100.0%    0+0k 0+0io 202pf+0w

Nice!

Pétur, do you like the final result? Regtesting is OK, and if I
don't hear from you, will test a little more and then commit to
mainline only, of course (for now).

Paolo.

/////////////
2004-04-23  Paolo Carlini  <pcarlini@suse.de>
	    Petur Runolfsson  <peturr02@ru.is>

	PR libstdc++/15002 (continued)
	* include/bits/istream.tcc (basic_istream<>::getline(char_type*,
	streamsize __n, char_type)): Use traits_type::find/copy in a loop
	to speed up greatly the function in the common case (I/O buffer
	size >> __n).

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

	* include/bits/istream.tcc (getline(basic_istream<>&,
	basic_string<>&, _CharT)): Change to use sgetc()/snextc() instead
	of sbumpc(), consistently with the other functions, thus also
	dealing correctly with the case of exceeded string::max_size().
diff -prN libstdc++-v3-orig/include/bits/istream.tcc libstdc++-v3/include/bits/istream.tcc
*** libstdc++-v3-orig/include/bits/istream.tcc	Sun Feb  8 05:46:41 2004
--- libstdc++-v3/include/bits/istream.tcc	Fri Apr 23 12:17:58 2004
***************
*** 1,6 ****
  // istream classes -*- C++ -*-
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
  // Free Software Foundation, Inc.
  //
  // This file is part of the GNU ISO C++ Library.  This library is free
--- 1,6 ----
  // istream classes -*- C++ -*-
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
  // Free Software Foundation, Inc.
  //
  // This file is part of the GNU ISO C++ Library.  This library is free
*************** namespace std
*** 592,618 ****
  	      const int_type __eof = traits_type::eof();
  	      __streambuf_type* __sb = this->rdbuf();
  	      int_type __c = __sb->sgetc();
! 
! 	      while (_M_gcount + 1 < __n
  		     && !traits_type::eq_int_type(__c, __eof)
  		     && !traits_type::eq_int_type(__c, __idelim))
  		{
! 		  *__s++ = traits_type::to_char_type(__c);
! 		  __c = __sb->snextc();
! 		  ++_M_gcount;
  		}
  	      if (traits_type::eq_int_type(__c, __eof))
  		__err |= ios_base::eofbit;
! 	      else
  		{
! 		  if (traits_type::eq_int_type(__c, __idelim))
! 		    {
! 		      __sb->sbumpc();
! 		      ++_M_gcount;
! 		    }
! 		  else
! 		    __err |= ios_base::failbit;
  		}
  	    }
  	  catch(...)
  	    { this->_M_setstate(ios_base::badbit); }
--- 592,636 ----
  	      const int_type __eof = traits_type::eof();
  	      __streambuf_type* __sb = this->rdbuf();
  	      int_type __c = __sb->sgetc();
! 	      --__n;
! 	      
! 	      while (_M_gcount < __n
  		     && !traits_type::eq_int_type(__c, __eof)
  		     && !traits_type::eq_int_type(__c, __idelim))
  		{
! 		  streamsize __size = std::min(streamsize(__sb->egptr()
! 							  - __sb->gptr()),
! 					       __n - _M_gcount);
! 		  if (__size > 1)
! 		    {
! 		      const char_type* __p = traits_type::find(__sb->gptr(),
! 							       __size,
! 							       __delim);
! 		      if (__p)
! 			__size = __p - __sb->gptr();
! 		      traits_type::copy(__s, __sb->gptr(), __size);
! 		      __s += __size;
! 		      __sb->gbump(__size);
! 		      _M_gcount += __size;
! 		      __c = __sb->sgetc();
! 		    }
! 		  else
! 		    {
! 		      *__s++ = traits_type::to_char_type(__c);
! 		      __c = __sb->snextc();
! 		      ++_M_gcount;
! 		    }
  		}
+ 
  	      if (traits_type::eq_int_type(__c, __eof))
  		__err |= ios_base::eofbit;
! 	      else if (traits_type::eq_int_type(__c, __idelim))
  		{
! 		  __sb->sbumpc();
! 		  ++_M_gcount;
  		}
+ 	      else
+ 		__err |= ios_base::failbit;
  	    }
  	  catch(...)
  	    { this->_M_setstate(ios_base::badbit); }
*************** namespace std
*** 1085,1106 ****
  	  try
  	    {
  	      __str.erase();
! 	      __int_type __idelim = _Traits::to_int_type(__delim);
! 	      __streambuf_type* __sb = __in.rdbuf();
! 	      __int_type __c = __sb->sbumpc();
  	      const __int_type __eof = _Traits::eof();
! 	      __testdelim = _Traits::eq_int_type(__c, __idelim);
  
! 	      while (!_Traits::eq_int_type(__c, __eof) && !__testdelim
! 		     && __extracted < __n)
  		{
  		  __str += _Traits::to_char_type(__c);
  		  ++__extracted;
- 		  __c = __sb->sbumpc();
- 		  __testdelim = _Traits::eq_int_type(__c, __idelim);
  		}
  	      if (_Traits::eq_int_type(__c, __eof))
  		__err |= ios_base::eofbit;
  	    }
  	  catch(...)
  	    {
--- 1103,1130 ----
  	  try
  	    {
  	      __str.erase();
! 	      const __int_type __idelim = _Traits::to_int_type(__delim);
  	      const __int_type __eof = _Traits::eof();
! 	      __streambuf_type* __sb = __in.rdbuf();
! 	      __int_type __c = __sb->sgetc();
  
! 	      while (__extracted < __n
! 		     && !_Traits::eq_int_type(__c, __eof)
! 		     && !_Traits::eq_int_type(__c, __idelim))
  		{
  		  __str += _Traits::to_char_type(__c);
+ 		  __c = __sb->snextc();
  		  ++__extracted;
  		}
  	      if (_Traits::eq_int_type(__c, __eof))
  		__err |= ios_base::eofbit;
+ 	      else if (_Traits::eq_int_type(__c, __idelim))
+ 		{
+ 		  __sb->sbumpc();
+ 		  ++__extracted;
+ 		}
+ 	      else
+ 		__err |= ios_base::failbit;
  	    }
  	  catch(...)
  	    {
*************** namespace std
*** 1110,1116 ****
  	      __in._M_setstate(ios_base::badbit);
  	    }
  	}
!       if ((!__extracted && !__testdelim) || __extracted == __n)
  	__err |= ios_base::failbit;
        if (__err)
  	__in.setstate(__err);
--- 1134,1140 ----
  	      __in._M_setstate(ios_base::badbit);
  	    }
  	}
!       if (!__extracted)
  	__err |= ios_base::failbit;
        if (__err)
  	__in.setstate(__err);

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