传递int是通过const引用还是值,有什么区别吗?

8

当我将像intdouble这样的基本类型传递给函数时,是通过const引用传递还是通过值传递更好(假设我不改变变量的值)?

int getValueFromArray(int index)
{
    // return the value from the array
}


int getValueFromArray(const int& index)
{
    // return the value from the array
}

谢谢

4个回答

10

对于原始类型,传值比传引用更好。不仅没有间接性,而且使用引用时,编译器必须担心潜在的别名问题,这可能破坏优化机会。

最后,通过引用传递会导致左值变为odr-used,这实际上可能导致链接器错误。即使调用被内联,这个问题也不会消失。


1
很多事情取决于编译器的优化级别。编译器优化可能会使整个问题无意义。此外,实现架构在某种程度上也起着作用。但是,一般来说,按值传递应该会稍微好一些。
理解引用实际上只是一个带有一些额外功能的指针是有帮助的。因此,检索参数的值涉及到从堆栈中获取此指针参数,然后进行另一个间接寻址以获取值,而不是直接从堆栈中读取参数的值。
但是这些差异大多是学术性质的。当参数不仅仅是 int 值时,这个问题变得更加重要。那么,选择是传递引用,不需要进一步工作,还是复制参数类的实例。这可能是昂贵的。

1
如果你通过const引用传递int,除非一个非常聪明的优化器检测到在所有情况下都可以只传递int值,否则你将支付一个(不必要的)间接层来访问它的值。
有时通过(const)引用传递int是有意义的,但实际上只有在编写模板代码并且不想为像int这样的基本数据类型创建额外的特殊化时才有意义。在正常情况下,与其通过const引用传递int,你最好传递int值,特别是当你处理函数签名类似于上面的函数时,在很多硬件上,int可以被传递到函数中的寄存器中。即使没有,它也在堆栈上具有良好的局部性引用。
对于double,情况有所改变,因为在某些架构上,将引用或指针传递给函数而不是值本身更有效率。然而,在最近的硬件上,与仅传递值相比,你最有可能因为间接层而失去性能。
在这两种情况下,具有相当激进的内联和特别是链接时代码生成的编译器/链接器将能够优化代码,以避免在处理代码生成器将内联的较小实用程序函数时在堆栈上进行任何参数传递。

1
如果数据类型可以适应处理器的寄存器,请通过复制(值)进行传递。更大的项目应通过引用传递。
您应该打印出两个示例的汇编语言清单,没有优化和高优化。使用更好的编译器,编译器将识别模式并执行最佳选择,通常通过值传递。
在汇编语言清单中,您可以看到编译器如何执行任何优化。
最坏情况下没有优化,常量引用通常通过指针传递实现。因此,指针将在寄存器中,而不是值。这意味着每当您访问变量时,首先要解除引用指针。这可能是一些额外的指令或处理器周期,但在执行和程序空间方面可能并不重要。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接