C++ C+的NRVO+;字符串
我试图找到一些关于名为返回值优化(NVRO)的std::string的信息。 我甚至不确定这是否适用,但我想知道从可读性和性能角度看,哪一个更好C++ C+的NRVO+;字符串,c++,c++14,nrvo,C++,C++14,Nrvo,我试图找到一些关于名为返回值优化(NVRO)的std::string的信息。 我甚至不确定这是否适用,但我想知道从可读性和性能角度看,哪一个更好 std::string first(const bool condition) { std::string info = "This"; info += condition ? " is" : " irrelevant"; //.append() info += " info.";
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;
}
std::字符串优先(常量布尔条件)
{
std::string info=“This”;
信息+=条件
“是”
:“无关”;/.append()
信息+=“信息。”;
return info;//这里是nrvo吗?
}
标准::字符串秒(常量布尔条件)
{
const auto firstPart=“第一部分”;
const auto anotherPart=条件
“第二部分”
:“无关”;/.append()
返回std::string{}.append(第一部分).append(另一部分);
}
标准::第三个字符串(常量布尔条件)
{
//如果字符串很长,由于可读性差,将避免
返回std::字符串{}
.附加(“第一部分”)
.附加(条件?“第二条”:“不相关”);
}
int main()
{
//printf(“你好世界”);
常数自动无关{true};
标准::cout
在C++11和14中,在这种情况下是允许的。从C++17中,返回值优化是强制性的(不再被视为复制省略)
通过查看三个候选函数@我看不出这一点,但我并没有做太多汇编工作。不过这看起来可能更干净一些:
您的第一个问题已由@Ted_Lyngom回答
如果您真的对性能感到担忧(并且测量结果证明此函数是您的热点)std::string在这种情况下有点太重。它不允许所有编译时优化,例如constepr
我建议使用std::string\u视图
#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();
}
如果使用print(true)
它将变为
main:
mov eax, 21
ret
因此,如果您以后使用这个句子,编译器将对它进行最佳优化
注:只有使用C++ 17编译器,否则,你只能使用。在这个地方编译器可以使用RVO。@ MigHalp这个问题仍然没有回答。没有任何建议的答案能起作用吗?谢谢,我的项目使用C++ 14,所以我猜“第二”。这将是最好的,但我认为这并不重要,因为这只是用于testing@MichałP.当然,您可以创建一个测试类,并查看您的C++14编译器如何处理它。它可能会省略复制,因为它被允许这样做。“在这种情况下允许省略复制”-我理解这是关于“第一”情况。“你当然可以创建一个测试类,看看你的C++14编译器是如何处理它的”-这也是关于“第一个”的吗?你能不能跟进一下“在C++11和14中,在这种情况下允许省略复制?”"-这是因为std::string impl吗?我不太熟悉复制省略,如果这个问题对您来说很愚蠢,那么很抱歉:)@MichałP。请将c++14标记添加到您的question@MichałP.这与string
无关,因此如果您创建自己的类并在所有五个类中使用调试打印实现,您可以检查C++14的编译方式er在您的三个示例中都处理了它。我猜在第一个示例中,您将看到最少的复制/移动量。字符串连接的示例会是什么样子?抱歉,我没有明确提到它,但这与“条件”一起是我的“问题”:我需要根据传递给函数的参数创建一个字符串。您不能直接创建。请给出您的具体需求。如果您发现这确实是您的热点,并且您只有2*2选项,您可以使用string\u view
对所有案例进行编码,如上所示。这将起作用,但不会增加可读性。如果您担心性能,首先分析整个程序,以确认担心是合理的。如果确实需要优化此代码,则在实际工作负载下、在实际平台上和使用实际编译器对其进行双向编码和分析。任何其他操作都是推测。您应使用sv
后缀:“这是相关信息”sv
因此长度信息可用于字符串视图
构造函数
main:
mov eax, 23
ret
main:
mov eax, 21
ret