通过引用存储函数的返回值是否有任何性能提升?

时间:2012-07-23 07:30:51

标签: c++ reference return-value

通过引用存储函数的返回值是否有任何性能提升?我的意思是以下代码首选,因为它可以防止将函数的返回值复制到变量?

string Foo()
{
    string someString = "some string";
    return someString;
}

const string &str = Foo();


修改虽然在上面的示例中Foo()正在返回一个字符串,但我的问题还涉及返回其他类型的对象。

5 个答案:

答案 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)。