You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@stdcxx.apache.org by "Travis Vitek (JIRA)" <ji...@apache.org> on 2008/01/30 02:51:34 UTC

[jira] Updated: (STDCXX-231) std::getline from header is rather slow

     [ https://issues.apache.org/jira/browse/STDCXX-231?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Travis Vitek updated STDCXX-231:
--------------------------------

    Attachment: stdcxx-231.patch

The issue is that the std::basic_string<...>::erase() method deallocates the string body, and then immediately reallocates a new one when we call append(). Obviously this is an unnecessary cost, and it can be quite expensive.

The std::basic_string<...>::clear(), erase() and replace() methods all have this behavior when resizing down to a zero length string. I'm inclined to believe that this is a simple mistake, but it is possible that it was done intentionally so that strings are deallocated when they become empty. My intention is to modify clear() and replace() to only deallocate the body when actually necessary. This will have the side effect that a string that has its size reduced to 0 will continue to hold the memory that it used prior to that resize. If a user wishes to deallocate this memory, they will have to use the following..

{noformat}
  // swap implementations with a null string to deallocate memory
  std::string ().swap (s);
{noformat}

Another option is to leave the current behavior for erase() and replace(), and to fix the issue for clear() [or vice-versa].

Here are the results of running the test before any changes...

{noformat}
$ time ./t-gcc 1000 /nfs/devco/vitek/stdcxx/trunk/tests/strings/21.string.io.cpp 
1291000

real    0m0.587s
user    0m0.563s
sys     0m0.021s
$ time ./t-stdcxx 1000 /nfs/devco/vitek/stdcxx/trunk/tests/strings/21.string.io.cpp
1291000

real    0m1.022s
user    0m0.907s
sys     0m0.068s
{noformat}

Here is the result after the patch...

{noformat}
$ time ./t-stdcxx 1000 /nfs/devco/vitek/stdcxx/trunk/tests/strings/21.string.io.cpp
1291000

real    0m0.309s
user    0m0.226s
sys     0m0.081s
{noformat}

Here is the changelog

{noformat}
2008-01-29  Travis Vitek  <vi...@roguewave.com>

	STDCXX-231
	* include/string (clear): Avoid deallocating string body unless
	necessary.
	* include/string.cc (replace): Ditto.
	* include/istream.cc (getline): Call clear() instead of erase()
	to avoid unnecessary overhead.
{noformat}




> std::getline from <string> header is rather slow
> ------------------------------------------------
>
>                 Key: STDCXX-231
>                 URL: https://issues.apache.org/jira/browse/STDCXX-231
>             Project: C++ Standard Library
>          Issue Type: Improvement
>          Components: 21. Strings
>    Affects Versions: 4.1.2, 4.1.3, 4.1.4, 4.2.0
>            Reporter: Martin Sebor
>            Assignee: Travis Vitek
>             Fix For: 4.2.1
>
>         Attachments: stdcxx-231.patch
>
>
> Moved from the Rogue Wave bug tracking database:
> ****Created By: leroy @ Jan 25, 2001 03:20:01 PM****
> Environment
>   Compiler : SUNPRO 4.2
>   OS : Solaris 2.5.1
>   SCL : 1.3.0 (Summer-1999)
>   Tools : 7.1.0 (Summer-1999) --> Use only for RWBench
> Command line option :
>   for debug : 
>   CC -xildoff +w +p -g -o Test_dbg.exe test.cc -DRWDEBUG=1 -I/opt/RogueWave/Summer-1999/workspaces/SOLARIS251/SUNPRO42/11s -I/opt/RogueWave/Summer-1999/workspaces/SOLARIS251/SUNPRO42/11s/include -I. -L/opt/RogueWave/Summer-1999/workspaces/SOLARIS251/SUNPRO42/11s/lib -Bstatic -ltls11s -lstd11s -Bdynamic
>   for release :
> CC -xildoff +w +p -fast -o Test_release.exe test.cc -I/opt/RogueWave/Summer-1999/workspaces/SOLARIS251/SUNPRO42/8s -I/opt/RogueWave/Summer-1999/workspaces/SOLARIS251/SUNPRO42/8s/include -I. -L/opt/RogueWave/Summer-1999/workspaces/SOLARIS251/SUNPRO42/8s/lib -Bstatic -ltls8s -lstd8s -Bdynamic
>  (Uploaded file: 997149-test.cc)                                                                                                                                                                                                                                                                                                                                                                                                   
> **** Entered By: Web @ Thursday, January 25, 2001 2:41:42 AM **** 
> Location of uploaded file: 
> http://thoth.bco.roguewave.com/uploads/997149-test.cc
> View all uploaded files for this incident: 
> http://webdev.roguewave.com/admin/tsvw/index.cfm?IncidentID=997149                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
> **** Entered By: Web @ Thursday, January 25, 2001 2:44:56 AM **** 
> #web
> Please find my test case at the end of the note
> Environment
>   Compiler : SUNPRO 4.2
>   OS : Solaris 2.5.1
>   SCL : 1.3.0 (Summer-1999)
>   Tools : 7.1.0 (Summer-1999) --> Use only for RWBench
> Command line option :
>   for debug : 
>   CC -xildoff +w +p -g -o Test_dbg.exe test.cc -DRWDEBUG=1 -I/opt/RogueWave/Summer-1999/workspaces/SOLARIS251/SUNPRO42/11s -I/opt/RogueWave/Summer-1999/workspaces/SOLARIS251/SUNPRO42/11s/include -I. -L/opt/RogueWave/Summer-1999/workspaces/SOLARIS251/SUNPRO42/11s/lib -Bstatic -ltls11s -lstd11s -Bdynamic
>   for release :
> CC -xildoff +w +p -fast -o Test_release.exe test.cc -I/opt/RogueWave/Summer-1999/workspaces/SOLARIS251/SUNPRO42/8s -I/opt/RogueWave/Summer-1999/workspaces/SOLARIS251/SUNPRO42/8s/include -I. -L/opt/RogueWave/Summer-1999/workspaces/SOLARIS251/SUNPRO42/8s/lib -Bstatic -ltls8s -lstd8s -Bdynamic
> #Code
> #include <string>
> #include <fstream.h>
> #include <iostream.h>
> #include <rw/bench.h>
>  
>  
> class std_string_getline : public RWBench
> {
>   public:
>    std_string_getline() {;}
>  
>    void doLoop(unsigned long n);
>    void idleLoop(unsigned long n);
>    void what(ostream& os) const { os << "Standard String Getline : " << endl;}
> };
>  
> class classic_getline : public RWBench
> {
>   public:
>     classic_getline() {;}
>  
>     void doLoop(unsigned long n);
>     void idleLoop(unsigned long n);
>     void what(ostream& os) const { os << "Classic Getline : " << endl;}
> };
>  
> int
> main(int argc, char** argv)
> {
>  
>   std_string_getline test_std_string;
>   test_std_string.parse(argc, argv);
>   test_std_string.go();
>   test_std_string.report(cout);
>  
>   classic_getline test_classic_getline;
>   test_classic_getline.parse(argc, argv);
>   test_classic_getline.go();
>   test_classic_getline.report(cout);
> }
>  
> void
> std_string_getline::doLoop(unsigned long n)
> {
>   while (n--)
>   {
>     ifstream toRead(__FILE__);
>     string line;
>     line.reserve(512);
>  
>     while (!(toRead.eof()))
>     {
>       getline(toRead, line, '\n');
>     }
>   }
> }
>  
> void
> std_string_getline::idleLoop(unsigned long n)
> {
>   while (n--)
>   {
>     ifstream toRead(__FILE__);
>     string line;
>     line.reserve(512);
>   }
> }
>  
> void
> classic_getline::doLoop(unsigned long n)
> {
>   while (n--)
>   {
>     ifstream toRead(__FILE__);
>     char cLine[512];
>     string line;
>     line.reserve(512);
>  
>     while (!(toRead.eof()))
>     {
>       toRead.getline(cLine, 512);
>       line = cLine;
>     }
>   }
> }
>  
> void
> classic_getline::idleLoop(unsigned long n)
> {
>   while (n--)
>   {
>     ifstream toRead(__FILE__);
>     char cLine[512];
>     string line;
>     line.reserve(512);
>   }
> }
> #EndCode                
> There appears to be something to this.  I ran the program and here is the output:
> Sun C++ 
> Standard String Getline : 
> Iterations:                 1
> Inner loop operations:      1000
> Total operations:           1000
> Elapsed (user) time:        18.18
> Operations per second:      55.0055
> Sun C++ 
> Classic Getline : 
> Iterations:                 5
> Inner loop operations:      1000
> Total operations:           5000
> Elapsed (user) time:        4.67
> Kilo-operations per second: 1.07066

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.