c++ Which is faster, returning a value in a function, or using a reference parameter?

时间:2015-04-24 21:29:50

标签: c++ function reference

Aside from what's the better or the most secure practice, is it generally faster to return a value in the function, or to just change the parameter by reference? Or is there an even faster method?

4 个答案:

答案 0 :(得分:2)

如果RVO没有启动,那么带有深层副本的大对象将很慢地按值返回。

但尺寸并不总是发挥作用。例如,返回1字节对象可能与返回2或4甚至8字节对象一样快,具体取决于平台。

通常不是关于什么是更快,而是在使用环境中需要什么。在原语的情况下,当意图输出值时,它通常由值返回。当对象标识有问题或意图是对实际对象的修改时,则通过引用返回。

还有可能的限制。例如,您永远不应该通过引用返回本地函数,因为这是一个等待发生的问题。您可以通过引用返回私有成员变量,但是再次,您可以简单地将其公开。

这也取决于你的意思"通过引用返回"因为这可能是通过引用返回的C ++样式,或者是通过指针返回的C样式。后者更频繁地使用,当你在一个函数中动态分配一个对象并且只返回一个指向它的指针时,如果是大的或唯一的对象,那么就是这样。

此外,除了RVO之外,还有移动语义,当按值返回时仍然会发挥作用。深层拷贝的开销是一个长期存在的问题,最近才在C ++ 11中得到解决。像Qt这样的一些框架通过使用浅拷贝和使用隐式共享资源来解决这个问题。

答案 1 :(得分:1)

It's going to depend on both the architecture of the processor and the specific implementation of the compiler.

In general, returning a reference may use one more indirection, so possibly 1-2 more instruction, but that's also a pathway that's so common there is probably some effort spent making it optimal.

So, as mentioned above, you would probably need to measure it. However, tiny changes in the code might change the optimization and so change the results.

As an academic exercise, it might be interesting, but the answer is indeterminate and the result is of little or no practical use.

答案 2 :(得分:0)

这在很大程度上取决于您实际想要返回什么样的价值以及您的功能是什么样的。例如。我们在讨论abuiltin类型,小/大POD,数组或具有非常昂贵的 copy 移动构造函数的对象吗? 特别重要的是功能结构是否如此,RVO / NRVO可以应用的问题。 (命名)返回值优化意味着编译器实际上并没有将局部变量复制到返回值中,而是直接在用于返回值的内存地址处构造局部变量。

如果返回值用于初始化调用站点的变量,或者更改已初始化的变量的值,这也很重要。编译器通常可以优化掉初始化,但不一定是修改

所以,例如以下代码:

struct Foo {
    int a;
};
Foo bar(){
    return Foo{ 5 };
}
int main() {
    Foo = bar();
}

将导致构造单个Foo对象而不执行任何复制。

除了可能消除复制任何东西的需要(甚至不是指针 - 通常可能通常被忽略),使用函数返回值还有另一个优点:
编译器可能在优化时更好,因为它没有传递指针/引用,所以它例如不必担心别名。

因此,如果您返回内置类型或小POD,最好使用返回值。另一方面,如果你必须更改数组中的值,那么当然最好使用指向该数组的指针,而不是返回一个数组,然后将其复制到目标数组中。

在大多数其他情况下: 取决于!

答案 3 :(得分:0)

经验法则: if(值是原始值) 然后按价值返回 否则以引用方式返回

如果速度不是问题,总是按值返回,那么你就不太可能以这种方式引入bug。