NRVO for C++ std::string

NRVO for C++ std::string

本文关键字:string std C++ for NRVO      更新时间:2023-10-16

我尝试查找有关 std::string 命名返回值优化 (NVRO( 的一些信息。我什至不确定这是否适用,但我想知道从可读性和性能 POV 来看哪个会更好。

std::string first(const bool condition)
{
    std::string info = "This";
    info += condition 
        ? " is" 
        : " irrelevant";  //.append()
    info += " info.";
    return info; // nrvo here?
}
std::string second(const bool condition)
{
    const auto firstPart = "First part";
    const auto anotherPart = condition 
        ? " second part" 
        : " irrelevant ";  //.append()
    return std::string{}.append(firstPart).append(anotherPart);
}
std::string third(const bool condition)
{
    //would avoid due to poor readability if strings are long
    return std::string{}
        .append("First part")
        .append(condition ? " second" : "irrelevant");
}
int main()
{
    // printf("Hello World");
    const auto irrelevant {true};
    std::cout<<first(irrelevant)<<std::endl;
    std::cout<<second(irrelevant)<<std::endl;
    std::cout<<third(irrelevant)<<std::endl;
    return 0;
}

如评论中所示:

  1. nvro会在"第一"中表演吗?

  2. 有没有更好的(更清洁/性能(方法来解决这个问题?

我的目的是创建一个帮助程序函数,该函数将根据给定的参数连接正确的字符串

  1. 在第 11 和 14 C++中,在这种情况下允许使用复制省略。从 C++17 开始,返回值优化是强制性的(不再被视为复制省略(。

  2. 不是说我可以通过查看三个候选函数@godbolt看到,但我没有做太多汇编程序。不过,这可能看起来更干净一些:

    std::string fourth(const bool condition) {
        return std::string{"First part "} += (condition ? "second" : "irrelevant");
    }

你的第一个问题已经被@Ted_Lyngmo问

如果你真的对性能很了解(并且测量证明这个函数是你的热点(,std::string在这种情况下有点太重了。它不允许所有编译时优化,例如constexpr

我建议使用std::string_view

#include <string_view>
constexpr std::string_view print(const bool condition) {
    if (condition){
        return "This is relevant info";
    } else {
        return "This is irrelevant info";
    }
}
int main() {
    std::string_view info = print(false);
    return info.size();
}

该程序将完全优化为

main:
        mov     eax, 23
        ret

如果您使用print(true)它将更改为

main:
        mov     eax, 21
        ret

因此,如果您之后使用该句子,编译器将最好对其进行优化。

注意:如果您有 C++17 编译器,则只能使用 string_view。