创建通过引用传递的新变量与按值传递时,是否有任何性能提升?

时间:2011-05-29 17:45:05

标签: performance variables reference

我对具体价值观不感兴趣,只是理论上的答案。

  1. 例如,在我们需要的循环中 在和上使用相同的值 结束,如果价值观会更快 将通过引用传递 价值?

  2. 那些对象呢?假设 我们的对象包含一些值 对于这个特定的例子 宾语。而不是实例化新的 对象,我们可以通过引用传递它 明智地获得表现?或者应该 我们clone吗?

  3. 我希望我已经说清楚了,先谢谢。

5 个答案:

答案 0 :(得分:3)

现代CPU的一般规则是“数学快,记忆慢”。

如果您正在谈论C ++,通过 value 传递整数,浮点数甚至小对象可能会更快。由于存在别名问题,传递引用可以防止各种编译器优化。

对于较大的对象,通过引用传递会更快。 (绝对不要克隆它们,因为内存很慢。)

但是,这个问题的真正答案是以自然,直接的方式编写代码,并且在您的分析器告诉您之前不要担心这类问题。

[更新,详细说明别名问题]

例如,请考虑以下两个函数:

void
foo1(int a, int b, int &c, int &d)
{
    c = a + b;
    d = a - b;
}

void
foo2(const int &a, const int &b, int &c, int &d)
{
    c = a + b;
    d = a - b;
}

启用优化后,我的编译器(gcc 4.5.2,x86_64)为foo1生成此代码:

leal    (%rsi,%rdi), %eax
subl    %esi, %edi
movl    %eax, (%rdx)
movl    %edi, (%rcx)
ret

...这对于foo2:

movl    (%rsi), %eax
addl    (%rdi), %eax
movl    %eax, (%rdx)
movl    (%rdi), %eax
subl    (%rsi), %eax
movl    %eax, (%rcx)
ret

您的编译器将执行类似的操作。问题是在foo2中,“c”或“d”可能指的是与“a”或“b”相同的内存位置,因此编译器必须插入额外的加载/存储来担心这种情况。

这是一个简单的例子,但更复杂的例子表现出类似的行为。对于简单类型甚至小结构,传递值通常会导致更快的代码。

答案 1 :(得分:1)

绝对。传递引用实际上总是一个很大的胜利,尤其是类的类型,其中必须运行一个非常重要的构造函数和析构函数。你可以期望pass-by-value获胜的唯一时间可能是传递小于指针的数据 - 例如单个字符 - 即使这样,它也是一个非常特定于硬件的参数。

答案 2 :(得分:1)

如果你感兴趣的只是表现,那么作为一般规则,通过引用传递比传递值更好。

答案 3 :(得分:1)

传递值复制值 - 如果它是一个小原语 - 比如说int,那就不重要了 - 你要么把int复制到堆栈来进行调用,要么你复制它的地址(相同的大小,粗略地说,没有真正的收获。)

对于一个大的非平凡对象,按值传递将会更加昂贵 - 您构建该对象的新副本。

目前还不清楚你对循环的意思 - PBV / PBR主要仅在函数调用期间起作用。

答案 4 :(得分:1)

这取决于语言和实施。通常,通过引用传递更快,因为您必须传递的是一个地址(指针)。对于小于指针的数据类型,可能节省内存和/或传递值的时间。但是,在大多数语言复制中,即使是小型对象,也需要调用某种类型的复制构造函数,这会消除任何可能的节省。另一方面,通过引用传递会创建一个对象或变量别名,在某些语言中这可能是一个问题。此外,在某些语言中,您无法通过引用传递编译时常量;编译器将调用func(1)转换为int _1 = 1; func(_1)

我还应该提到,在某些语言(如Java)中,不可能通过引用按值或原始类型传递对象。当然,对于这些语言,你的问题没有实际意义。