为什么const int比const int&?更快?

时间:2012-03-09 16:48:52

标签: c++ visual-c++

有一天我意外地注意到了这一点,现在决定对它进行广泛的测试。

所以,当我调用一个函数时:

#define Type int
#define Prm const Type &
Type testfunc1(Prm v1, Prm v2, Prm v3, Prm v4, Prm v5, Prm v6, Prm v7, Prm v8, Prm v9, Prm v10){
    return (v1|v2|v3|v4|v5|v6|v7|v8|v9|v10);
}

1亿次:

        for(Type y = 0; y < 10000; y++){
            for(Type x = 0; x < 10000; x++){
                out |= testfunc1(x,y,x,x,y,y,x,y,x,y);
            }
        }

对于intconst intconst int &类型,我注意到const intconst int &快。 (注意:我使用返回值来确保函数不会被优化掉)。

为什么会这样?我一直认为添加&实际上会让它更快,但测试却反过来说。我知道对于更大的数据类型,它可能会有不同的结果,但我没有测试过,因为我对结果非常肯定。

我的测试:

const int: 7.95s
const int &: 10.2s

编辑:我认为这确实是因为我的架构;我使用Sint64类型进行了测试,结果是:

const Sint64: 17.5s
const Sint64 &: 16.2s

编辑2:或者是吗?用double类型(64位?)进行测试,结果让我感到困惑:

const double: 11.28s
const double &: 12.34s

Edit3:更新了循环代码,使我的最新测试与64位类型匹配。

3 个答案:

答案 0 :(得分:9)

通过在参数中加入&,您将向程序添加更多代码。如果没有&,则序列为:

 push values
 call Function
 pop values <- usually an update to stack pointer

和功能:

 return sp[arg1] | sp[arg2] | etc <- value read direct from stack.

添加'&amp;'这样做:

 push address of value1
 push address of value2
 etc
 call Function
 pop values <- usually an update to stack pointer

和功能:

 return_value = 0;
 address = sp[arg1]
 or return_value, [address]
 address = sp[arg2]
 or return_value, [address]
 etc
 return return_value

因此,正如您所看到的,&增加了很多。那么为什么要用呢?如果你有一个非常大的对象,传递指针比将对象复制到堆栈更合理。

答案 1 :(得分:7)

此结果严重依赖于系统。它表明在您的特定系统上复制引用的值(最有可能实现为指针)比复制整数值的成本更高。这种差异的最可能原因是您的整数需要32位来表示,而您的指针/引用表示需要64位。 编辑这就是访问整数的成本:获取它们的值需要额外的间接。由于您只传递了两个项目,因此使用缓存会在很大程度上隐藏额外的成本,但成本就在那里。

你对大型类型绝对正确:将引用传递给大型structvector<...>仍然只需要64位(或者系统中的大小),无论您的结构有多少项目,或vector<...>拥有多少项目。结构越大,通过价值传递的成本就越高,因此通过将其作为参考来实现节省。

答案 2 :(得分:1)

传递地址而不是值会导致地址转义(在您喜欢的编译器教科书中查找转义分析或指向分析),使得优化更加困难。

是的,内联和链接时优化等内容可以缓解这些问题。