Summary: | [3.4 only] Linewise stream input is unusably slow (std::string slow) | ||
---|---|---|---|
Product: | gcc | Reporter: | aaron |
Component: | libstdc++ | Assignee: | Paolo Carlini <paolo.carlini> |
Status: | RESOLVED FIXED | ||
Severity: | enhancement | CC: | gcc-bugs |
Priority: | P2 | ||
Version: | 3.3.3 | ||
Target Milestone: | 3.4.1 | ||
Host: | i686-debian-linux | Target: | i686-debian-linux |
Build: | i686-debian-linux | Known to work: | 4.0.0 |
Known to fail: | 3.4.0 | Last reconfirmed: | 2004-04-18 14:20:12 |
Attachments: |
The test case
The gprof output for the streams program |
Description
aaron
2004-04-18 14:06:29 UTC
Created attachment 6111 [details]
The test case
Unpack it and run 'make test'. Notice that it'll create a temporary file of
about 40MB!
Created attachment 6112 [details]
The gprof output for the streams program
The complete output of 'gprof -q' on the 'streams' test program.
Confirmed, the issue might be using wrong std::string functions to do std::getline. Otherwise std:: string is where it is slow. That's not true. std::getline() is HORRIBLY slow (more than 30 times slower than fgets()), basically making it unusable to read large files. std::ifstream::getline() is still VERY slow (more than 4 times slower than fgets()), which still makes it nearly unusable. This might not be a 'critical' bug, but it has at least severity 'normal' because almost every serious C++ program uses linewise input somewhere. Anyway, I leave it to you to change that if you feel like :-) Well for the mainline it is already faster: tin:~/src/gnu/gcctest/iotest/iotest>time ./streams 3.510u 0.040s 0:03.69 96.2% 0+0k 0+0io 202pf+0w tin:~/src/gnu/gcctest/iotest/iotest>time ./streams2 0.420u 0.040s 0:00.69 66.6% 0+0k 0+0io 200pf+0w tin:~/src/gnu/gcctest/iotest/iotest>time ./stdio 0.090u 0.060s 0:00.14 107.1% 0+0k 0+0io 80pf+0w But since this has never been fast, it is an enhancement. Subject: Bug 15002 CVSROOT: /cvs/gcc Module name: gcc Changes by: paolo@gcc.gnu.org 2004-04-19 11:30:21 Modified files: libstdc++-v3 : ChangeLog libstdc++-v3/include/bits: basic_string.h Log message: 2004-04-19 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. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.diff?cvsroot=gcc&r1=1.2452&r2=1.2453 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/basic_string.h.diff?cvsroot=gcc&r1=1.58&r2=1.59 Paolo, your patch helped a lot (I looked a profile generated by Shark). I noticed that most of the time now is spent in std::string::_M_mutate from std::string::_M_replace_aux, not doing much at all. Some suggestions after looking into the source/asm: The calculation for __src could be moved inside the if statements, removing a load and two adds. On the same box as before after Paolo's patch, so a little more than a 2x speedup: tin:~/src/gnu/gcctest/iotest/iotest>time ./streams 1.340u 0.100s 0:01.43 100.6% 0+0k 0+0io 202pf+0w tin:~/src/gnu/gcctest/iotest/iotest>time ./streams2 0.430u 0.010s 0:00.44 100.0% 0+0k 0+0io 199pf+0w tin:~/src/gnu/gcctest/iotest/iotest>time ./stdio 0.080u 0.060s 0:00.15 93.3% 0+0k 0+0io 80pf+0w Thanks Andrew for testing again and in particular for your suggestion! Subject: Bug 15002 CVSROOT: /cvs/gcc Module name: gcc Branch: hammer-3_3-branch Changes by: paolo@gcc.gnu.org 2004-04-23 14:44:40 Modified files: libstdc++-v3 : ChangeLog.hammer libstdc++-v3/include/bits: basic_string.tcc Log message: 2004-04-23 Paolo Carlini <pcarlini@suse.de> PR libstdc++/15002 (partial) * include/bits/basic_string.tcc (_M_replace_safe, replace(iterator, iterator, size_type, _CharT)): Special case __dnew/__n2 == 1, not calling _S_copy_chars/traits_type::assign. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.hammer.diff?cvsroot=gcc&only_with_tag=hammer-3_3-branch&r1=1.1.2.10&r2=1.1.2.11 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/basic_string.tcc.diff?cvsroot=gcc&only_with_tag=hammer-3_3-branch&r1=1.28.2.6&r2=1.28.2.7 Subject: Bug 15002 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_4-branch Changes by: paolo@gcc.gnu.org 2004-04-24 09:09:53 Modified files: libstdc++-v3 : ChangeLog libstdc++-v3/include/bits: basic_string.h basic_string.tcc Log message: 2004-04-24 Paolo Carlini <pcarlini@suse.de> Andrew Pinski <pinskia@physics.uc.edu> * include/bits/basic_string.tcc (_M_mutate): Don't compute __src unnecessarily. 2004-04-24 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. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.2224.2.82&r2=1.2224.2.83 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/basic_string.h.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.41.4.3&r2=1.41.4.4 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/basic_string.tcc.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.46.4.5&r2=1.46.4.6 Subject: Bug 15002 CVSROOT: /cvs/gcc Module name: gcc Changes by: paolo@gcc.gnu.org 2004-04-24 22:20:31 Modified files: libstdc++-v3 : ChangeLog libstdc++-v3/include/bits: istream.tcc Added files: libstdc++-v3/testsuite/27_io/basic_istream/getline/char: 4.cc Log message: 2004-04-24 Paolo Carlini <pcarlini@suse.de> Petur Runolfsson <peturr02@ru.is> PR libstdc++/15002 (continued) * include/bits/istream.tcc (basic_istream<>::getline(char_type*, streamsize, char_type)): Use traits::find/copy in a loop to speed up greatly the function in the common case (I/O buffer size >> 1). 2004-04-24 Paolo Carlini <pcarlini@suse.de> * testsuite/27_io/basic_istream/getline/char/4.cc: New. * 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(). Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.diff?cvsroot=gcc&r1=1.2459&r2=1.2460 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/istream.tcc.diff?cvsroot=gcc&r1=1.61&r2=1.62 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/getline/char/4.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1 Subject: Bug 15002 CVSROOT: /cvs/gcc Module name: gcc Changes by: paolo@gcc.gnu.org 2004-04-25 15:45:14 Modified files: libstdc++-v3 : ChangeLog libstdc++-v3/include/bits: istream.tcc basic_string.tcc libstdc++-v3/testsuite/27_io/basic_istream/getline/char: 4.cc Log message: 2004-04-25 Paolo Carlini <pcarlini@suse.de> PR libstdc++/15002 (continued again) * include/bits/istream.tcc (getline(basic_istream<>&, basic_string<>&, _CharT)): Use a temporary buffer, thus avoiding reallocation for common case. * include/bits/basic_string.tcc (_S_construct(_InIterator, _InIterator, const _Alloc&, input_iterator_tag)): Tweak size of temporary buffer to a power of two. * testsuite/27_io/basic_istream/getline/char/4.cc: Add comment. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.diff?cvsroot=gcc&r1=1.2461&r2=1.2462 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/istream.tcc.diff?cvsroot=gcc&r1=1.62&r2=1.63 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/basic_string.tcc.diff?cvsroot=gcc&r1=1.69&r2=1.70 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/getline/char/4.cc.diff?cvsroot=gcc&r1=1.1&r2=1.2 This is now fixed on the mainline: tin:~/src/gnu/gcctest/iotest/iotest>time ./streams2 0.100u 0.040s 0:00.14 100.0% 0+0k 0+0io 205pf+0w tin:~/src/gnu/gcctest/iotest/iotest>time ./stdio 0.080u 0.050s 0:00.14 92.8% 0+0k 0+0io 85pf+0w tin:~/src/gnu/gcctest/iotest/iotest>time ./streams 0.420u 0.070s 0:00.49 100.0% 0+0k 0+0io 208pf+0w Which makes using streams to very close to running stdio. Paolo says he is going to try to get this into 3.4.1 also. Subject: Bug 15002 CVSROOT: /cvs/gcc Module name: gcc Branch: hammer-3_3-branch Changes by: paolo@gcc.gnu.org 2004-05-02 16:10:34 Modified files: libstdc++-v3 : ChangeLog.hammer libstdc++-v3/include/bits: istream.tcc Log message: 2004-05-02 Paolo Carlini <pcarlini@suse.de> PR libstdc++/15002 (continued) * include/bits/istream.tcc (getline(basic_istream<>&, basic_string<>&, _CharT)): Use a temporary buffer, thus avoiding reallocation for common case. * 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(). Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.hammer.diff?cvsroot=gcc&only_with_tag=hammer-3_3-branch&r1=1.1.2.12&r2=1.1.2.13 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/istream.tcc.diff?cvsroot=gcc&only_with_tag=hammer-3_3-branch&r1=1.36.2.7&r2=1.36.2.8 Subject: Bug 15002 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_4-branch Changes by: paolo@gcc.gnu.org 2004-05-09 23:27:57 Modified files: libstdc++-v3 : ChangeLog libstdc++-v3/include/bits: basic_string.tcc istream.tcc Added files: libstdc++-v3/testsuite/27_io/basic_istream/getline/char: 4.cc 5.cc libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char: 10.cc libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t: 10.cc Log message: 2004-05-09 Paolo Carlini <pcarlini@suse.de> * testsuite/21_strings/basic_string/inserters_extractors/char/10.cc: New. * testsuite/21_strings/basic_string/inserters_extractors/wchar_t/10.cc: Likewise. * testsuite/27_io/basic_istream/getline/char/5.cc: Likewise. 2004-05-09 Paolo Carlini <pcarlini@suse.de> PR libstdc++/15002 (continued again) * include/bits/istream.tcc (getline(basic_istream<>&, basic_string<>&, _CharT)): Use a temporary buffer, thus avoiding reallocation for common case. * include/bits/basic_string.tcc (_S_construct(_InIterator, _InIterator, const _Alloc&, input_iterator_tag)): Tweak size of temporary buffer to a power of two. * testsuite/27_io/basic_istream/getline/char/4.cc: Add comment. 2004-05-09 Paolo Carlini <pcarlini@suse.de> Petur Runolfsson <peturr02@ru.is> PR libstdc++/15002 (continued) * include/bits/istream.tcc (basic_istream<>::getline(char_type*, streamsize, char_type)): Use traits::find/copy in a loop to speed up greatly the function in the common case (I/O buffer size >> 1). 2004-05-09 Paolo Carlini <pcarlini@suse.de> * testsuite/27_io/basic_istream/getline/char/4.cc: New. * 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(). Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.2224.2.96&r2=1.2224.2.97 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/basic_string.tcc.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.46.4.6&r2=1.46.4.7 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/istream.tcc.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.60.4.2&r2=1.60.4.3 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/getline/char/4.cc.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.2.4.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/getline/char/5.cc.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.4.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/10.cc.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.4.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/10.cc.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.4.1 Fixed for 3.4.1. |