Code Comparison : Which code is better to use in terms of efficiency?

Refresh

April 2019

Views

109 time

-2

Which code is better to use : to initialize string ?

bool flag = /*function call...*/
string str = "abc";
if(flag)
  str = "bcd";

Or

string str;
if(flag)
  str = "bcd";
else
  str = "abc";

Or

string str("abc");
if(flag) 
  str = "bcd";

Thanks in advance.

2 answers

2

The C++ way is to use initialization:

bool flag = foo();
string str { flag ? "bcd" : "abc" };

flag determines which string literal is used in the call to std::string::string(const char*). But there's one call, one string object being constructed, and no assignment.

[edit] Flipped the string literals. In C++, both for the if construct and the ?: construct, the "true" case comes first, and then "false" case last. But the question had them reversed, "abc" came first for the flag==false case.

9

This is a micro optimization you should not be doing. A C++ program is not a description of assembly in human readable format. It's a a high level description of the behavior your program should have. The compiler's job is to emit assembly that exhibits the behavior we specified.

You didn't specify how you use the resultant string, but if I make a few a assumptions and turn your code into small functions...

#include <string>

std::string foo1(bool flag) {
    std::string str = "abc";
    if(flag)
        str = "bcd";
    return str;
}

std::string foo2(bool flag) {
    std::string  str;
    if(flag)
        str = "bcd";
    else
        str = "abc";
    return str;
}

std::string foo3(bool flag) {
    std::string str("abc");
    if(flag) 
        str = "bcd";
    return str;
}

.. Clang 8.0 will produce pretty much equivalent assembly for the three cases (and especially for foo1 and foo3)1. You can see it on Godbolt.

Which is no surprise, since the observable behavior your three snippets dictate is the same, and not affected by which snippet you chose. So don't dwell on micro optimizations. Dwell on describing optimal behavior on a greater scale.


1 - Well, there is a noticeable branch in foo2, but the code that will be executed at runtime is still always going to be one potential allocation and a copy of the string's contents. There may be some cost on branch misprediction here, but unless it's in a really tight loop, I wouldn't consider it worth considering. Moreover, the use of std::string in a such a loop may be deemed questionable itself.