public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/59048] New: std::string operator== between std::string and const char* creates unecessary temporary object
@ 2013-11-08 10:59 luca.stoppa at bbh dot com
  2013-11-08 11:12 ` [Bug libstdc++/59048] " redi at gcc dot gnu.org
                   ` (17 more replies)
  0 siblings, 18 replies; 19+ messages in thread
From: luca.stoppa at bbh dot com @ 2013-11-08 10:59 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59048

            Bug ID: 59048
           Summary: std::string operator== between std::string and const
                    char* creates unecessary temporary object
           Product: gcc
           Version: 4.4.7
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: luca.stoppa at bbh dot com

Template functions
bool operator==( const char*, const std::string& ) and
bool operator==( const std::string&, const char* )
creates unecessary temporary std::string object. I'm using mainly GCC 4.4.7,
but I have tested GCC 4.8.3 and the behavior is exactly the same.

Look at this simple example:
1) here we call operator==(std::string&, const char*):
size_t f(const std::string &str)
{
    size_t result = 0;
    size_t len = str.size();
    for (size_t i=0; i<len; ++i)
        if (str == "ST")
            result += i;
    return result;
}

2) here we call operator==(const char*, const std::string&)
size_t h(const std::string &str)
{
    size_t result = 0;
    size_t len = str.size();
    for (size_t i=0; i<len; ++i)
        if ("ST" == str)
            result += i;
    return result;
}

3) here a basic const char* version
size_t ii(const char *str)
{
    size_t result = 0;
    size_t len = strlen(str);
    for (size_t i=0; i<len; ++i)
        if (0 == strcmp(str,"ST"))
            result += i;
    return result;
}

4) here a mixed version: std::string compared with strcmp().
size_t g(const std::string &str)
{
    size_t result = 0;
    size_t len = str.size();
    for (size_t i=0; i<len; ++i)
        if (0 == strcmp(str.c_str(),"ST"))
            result += i;
    return result;
}

This is the main I used to test these functions:
int main(int argc, char **argv )
{
    long how_many_times=atol( argv[1] );
    std::string events[]={ "CASH", "EQ", "FI", "FT", "FWD", "OP", "ST" };
    size_t result=0;
    for (size_t i=0; i<how_many_times; ++i)
        for (size_t j=0; j<elements(events); ++j)
            result += f(events[j]);

    std::cout <<result <<std::endl;
    return 0;
}

Few things to notice: running time ./a.out
f() will produce:
bash-4.1$ time ./a.out 10000000
10000000
real    0m4.222s

g() will produce:
bash-4.1$ time ./a.out 10000000
10000000
real    0m1.036s

h() will produce:
bash-4.1$ time ./a.out 10000000
10000000
real    0m4.223s

ii() (if we change in main() std::string events[]={...} into const char*
events[]={...}) will produce:
bash-4.1$ time ./a.out 10000000
10000000
real    0m1.266s
if I remove the call to strlen() will be basically 0seconds.

Which is the problem?
The problem here is that: why f()/h() are taking basically 4times more then
g()? The only different is how we compare strings. It seems like that f() and
h() are creating a temporary std::string object. Shouldn't we have the same
performance? It seems like the compare() method of the char_trait<char> could
be better implemented.

As a final notice: I have compiled all examples with g++ -O3 (Linux 64 and
MacOS Snow Lion).


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2022-06-14 20:21 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-08 10:59 [Bug c++/59048] New: std::string operator== between std::string and const char* creates unecessary temporary object luca.stoppa at bbh dot com
2013-11-08 11:12 ` [Bug libstdc++/59048] " redi at gcc dot gnu.org
2013-11-08 11:18 ` redi at gcc dot gnu.org
2013-11-08 11:34 ` luca.stoppa at bbh dot com
2013-11-08 11:37 ` paolo.carlini at oracle dot com
2013-11-08 11:41 ` luca.stoppa at bbh dot com
2013-11-08 11:46 ` paolo.carlini at oracle dot com
2013-11-08 11:46 ` redi at gcc dot gnu.org
2013-11-08 11:50 ` paolo.carlini at oracle dot com
2013-11-08 13:48 ` luca.stoppa at bbh dot com
2013-11-08 19:24 ` glisse at gcc dot gnu.org
2015-06-02 22:49 ` [Bug libstdc++/59048] operator== between std::string and const char* slower than strcmp neleai at seznam dot cz
2015-06-03  6:34 ` manu at gcc dot gnu.org
2015-06-03  7:54 ` glisse at gcc dot gnu.org
2021-02-11 20:08 ` hiraditya at msn dot com
2021-02-12 14:48 ` redi at gcc dot gnu.org
2022-06-14 15:15 ` redi at gcc dot gnu.org
2022-06-14 20:19 ` cvs-commit at gcc dot gnu.org
2022-06-14 20:21 ` redi at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).