代码比较:就效率而言,使用哪种代码更好?

时间:2019-04-23 06:25:16

标签: c++ string copy-constructor assignment-operator

哪种代码更适合使用:初始化字符串?

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

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

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

谢谢。

2 个答案:

答案 0 :(得分:9)

这是您不应该做的微优化。 C ++程序不是是以人类可读格式描述的程序集。这是程序应具有的行为的高级描述。编译器的工作是发出具有我们指定行为的程序集。

您没有指定如何使用结果字符串,但是如果我作一些假设并将您的代码转换为小函数...

#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在这三种情况下(特别是对于foo1foo3)会产生几乎相同的汇编 1 。您可以在Godbolt上看到它。

这不足为奇,因为您的三个代码片段指示的可观察行为是相同,并且不受所选代码片段的影响。因此,不要只关注微优化。请继续详细描述最佳行为。


1 -好吧,foo2中有一个 分支,但是将在运行时执行的代码始终始终是一个潜在的分配和字符串内容的副本。这里的分支错误预测可能会花费一些成本,但是除非它处于真正的紧密循环中,否则我认为这是不值得考虑的。此外,在这样的循环中使用std::string本身可能会引起怀疑。

答案 1 :(得分:2)

C ++方法是使用初始化:

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

flag确定在调用std::string::string(const char*)中使用哪个字符串文字。但是只有一个调用,正在构造一个字符串对象,并且没有分配。

[编辑] 翻转字符串文字。在C ++中,对于if构造和?:构造,“ true”情况首先出现,然后是“ false”情况。但是问题是他们推翻了,flag==false案例中“ abc”是第一位。