当我将int
和double
这样的原语传递给函数时,最好是通过const引用或值传递它们(假设我不改变变量' s值)?
int getValueFromArray(int index)
{
// return the value from the array
}
int getValueFromArray(const int& index)
{
// return the value from the array
}
由于
答案 0 :(得分:5)
对于基本类型,传递值比通过引用传递要好得多。不仅没有间接,而且通过引用,编译器必须担心潜在的混叠,这可能会破坏优化机会。
最后,pass-by-reference导致lvalues变得使用odr,这实际上可能导致链接器错误。如果电话被内联,这个最后的问题不会消失。
答案 1 :(得分:1)
很大程度上取决于编译器的优化级别。编译器优化可能会使整个问题变得毫无意义。此外,实现架构在某种程度上起了作用。但是,一般来说,通过价值会稍微好一些。
有助于理解引用实际上只是一个指针,顶部有一些糖。因此,检索参数的值涉及将此指针参数从堆栈中取出,然后进行另一个取消引用以获取值,而不是直接从堆栈中读取参数的值。
但差异主要是学术性的。当参数不仅仅是一个int值时,这个问题变得更加重要。然后,选择归结为传递引用,而不需要进一步的工作,而不是复制参数类的实例。这可能很贵。
答案 2 :(得分:1)
如果你通过const引用传递int,你将最终支付一个(不必要的)间接层的惩罚来访问它的值,除非一个非常聪明的优化器检测到它可以通过在所有情况下的int值。
有时通过(const)引用传递和int是有意义的,但实际上只有在编写模板化代码并且不想为原始数据类型(如int
)创建其他特化时。在正常情况下,最好通过值int
而不是const引用传递,特别是在许多硬件上,当你处理函数时,int可以传递给寄存器中的函数签名就像你上面的签名。即使没有,它也就在堆栈上,具有良好的参考位置。
对于double
,图片会有所改变,因为在某些体系结构上,将引用或指针传递给函数而不是值本身更有效。但是,在最近的硬件上,与传递值相比,由于间接层,您最有可能失去性能。
在这两种情况下,具有相当积极的内联,特别是链接时间代码生成的编译器/链接器将能够优化代码,以避免任何参数在堆栈上传递,如果您正在处理代码的较小实用程序函数发电机将内联。
答案 3 :(得分:1)
如果数据类型适合处理器的寄存器,则按副本(值)进行传递。较大的项目应通过引用传递。
您应打印出两个示例的汇编语言列表,无需优化和高优化。使用更好的编译器,编译器将识别模式并执行最佳选择,通常按值传递。
在汇编语言列表中,您可以看到编译器如何执行任何优化。
最糟糕的情况是,没有优化,通常通过传递指针来实现常量引用。因此,指针不是在寄存器中具有值,而是在寄存器中。这意味着无论何时访问变量,您都要先取消引用指针。这可能是一些额外的指令或处理器周期,但在执行和程序空间中可能并不重要。