This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch] Fix libstdc++/15002 (continued)
- From: Paolo Carlini <pcarlini at suse dot de>
- To: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Cc: Pétur Runólfsson <peturr02 at ru dot is>
- Date: Fri, 23 Apr 2004 12:23:55 +0200
- Subject: [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);