有一天我意外地注意到了这一点,现在决定对它进行广泛的测试.
所以,当我调用一个函数时:
#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);
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
对于类型int,const int而且const int &,我注意到它const int比const int &.(注意:我使用返回值来确保函数不会被优化掉).
为什么会这样?我一直认为添加&实际上会让它更快,但测试反过来说.我知道对于更大的数据类型,它可能会有不同的结果,我没有测试那些,因为我非常肯定结果.
我的测试:
const int: 7.95s
const int &: 10.2s
Run Code Online (Sandbox Code Playgroud)
编辑:我认为这确实是因为我的架构; 我测试了Sint64类型,结果如下:
const Sint64: 17.5s
const Sint64 &: 16.2s
Run Code Online (Sandbox Code Playgroud)
编辑2:或者是吗?测试double类型(64位?),结果让我感到困惑:
const double: 11.28s
const double &: 12.34s
Run Code Online (Sandbox Code Playgroud)
Edit3:更新了循环代码,使我的最新测试与64位类型相匹配.
通过&在参数中加入,您将向程序添加更多代码.没有&,序列是:
push values
call Function
pop values <- usually an update to stack pointer
Run Code Online (Sandbox Code Playgroud)
和功能:
return sp[arg1] | sp[arg2] | etc <- value read direct from stack.
Run Code Online (Sandbox Code Playgroud)
添加'&'可以做到这一点:
push address of value1
push address of value2
etc
call Function
pop values <- usually an update to stack pointer
Run Code Online (Sandbox Code Playgroud)
和功能:
return_value = 0;
address = sp[arg1]
or return_value, [address]
address = sp[arg2]
or return_value, [address]
etc
return return_value
Run Code Online (Sandbox Code Playgroud)
所以,正如你所看到的,&增加了许多.那么为什么要用呢?如果您有一个非常大的对象,则传递指针比将对象复制到堆栈更为理想.
该结果严重依赖于系统.它表明在您的特定系统上复制引用的值(最有可能实现为指针)比复制整数值的成本更高.这种差异的最可能原因是您的整数需要32位来表示,而您的指针/引用表示需要64位.编辑这并不是说访问整数的成本:获取它们的值需要额外的间接.由于您只传递了两个项目,因此使用缓存会在很大程度上隐藏额外成本,但成本却存在.
但是,对于较大的类型,你绝对正确:将引用传递给大型struct或者vector<...>仍然只需要64位(或者系统上的任何大小),无论您的结构有多少项,或者有多少项你的vector<...>.结构越大,通过价值传递的成本就越高,因此通过将其作为参考来实现节省.