通过引用存储函数的返回值是否有任何性能提升?我的意思是以下代码首选,因为它可以防止将函数的返回值复制到变量?
string Foo()
{
string someString = "some string";
return someString;
}
const string &str = Foo();
修改虽然在上面的示例中Foo()
正在返回一个字符串,但我的问题还涉及返回其他类型的对象。
答案 0 :(得分:4)
在C ++中实现字符串的方式是一个字符数组。因此,当您使用引用时,主要优点是可以避免成员方式的副本,并且指向的对象是已经传递的对象。这可以提高涉及大字符串或数组的性能。对于你的例子,字符串非常短,并不重要!希望这有助于:)。
答案 1 :(得分:3)
没有。事实上,可能会有轻微的性能损失 (虽然我对此表示怀疑)。关于你通过使用这里的参考获得的所有 案件是混淆。
答案 2 :(得分:2)
今天编译器非常聪明,在这种情况下可能会使用RVO(返回值优化)。因此,即使按值返回,也不会存在复制开销
你应该遵循的主要规则是编写一个好的可读代码(因为代码是为人们编写的),只有在需要时才会进行优化,并且只有在找到瓶颈之后才会进行优化
答案 3 :(得分:1)
知道,你不会获得性能提升。在这种情况下,您可以使用std :: move()获得提升。
答案 4 :(得分:1)
您的代码包含Foo
中的两个副本:
(1)从使用string
构造函数构建的const char*
类型的临时对象转移到someString
。
(2)从变量someString
到临时对象,它是Foo
的返回值。
您正在撰写const string &str = Foo();
而不是const string str = Foo();
,目的是阻止第三份副本:
(3)从临时对象(Foo
的返回值到str
。
标准允许所有三个副本被删除,所以问题基本上是你的编译器是否需要3的帮助。
根据经验,我会说不 - 如果你的编译器足够聪明,可以忽略第1和第2副本,那么它很可能足够聪明地消除3.如果它不够聪明而不能忽略它们中的任何一个,并且这会降低您的性能,然后您需要处理函数Foo
以及调用它的代码。但是这种情况不会出现 - 只要你记得打开优化,任何真正的C ++编译器都可以复制省略。
可能会出现这样一种特殊情况:您需要仔细编写代码,以帮助编译器找不到允许忽略的副本。您需要在发生这些情况时找到它们,没有一般的编码指南可以(准确地)告诉您需要担心(3)而不是(1)和(2)。