这是一个关于64位整数的效率问题。假设我不需要修改“int”参数的值,我应该通过值或引用传递它。
假设32位机器:
1)32位int:我猜答案是“按值传递”,因为“按引用传递”将有额外的内存查找开销。
2)64位int:如果我通过引用传递,我只在栈上传递32位地址,但需要额外的内存查找。那么哪一个更好(参考或价值)?
如果机器是64位怎么办?
的问候,
JP
答案 0 :(得分:9)
通过价值 - 肯定。如果系统是64位,则意味着它可以非常快速地复制64位字。
答案 1 :(得分:8)
即使在64位机器上,传递值也更好(除了极少数例外),因为它可以作为寄存器值传递。
答案 2 :(得分:7)
将它们作为boost::call_traits<int64_t>::param_type
传递。此模板捕获在支持的平台上传递任何类型的最佳实践。因此,它在32位和64位平台上会有所不同,但您可以在任何地方使用相同的代码。它甚至适用于您还不知道精确类型的其他模板。
答案 3 :(得分:4)
出于论证的缘故,让我们忽略优化器删除差异的微不足道的情况。我们还说你正在使用微软的英特尔64位调用约定(它与Linux ABI不同),那么你必须有4个64位寄存器来传递这些值,然后才能在堆栈上推送它们。这显然更好。
对于32位应用程序,按值并且它们会直接进入堆栈。引用可以改为将指针放在寄存器中(同样,在求助于堆栈之前允许一些这样的寄存器使用)。我们可以在g ++ -O3 -S的某些输出中,通过值调用f1(99)和通过const引用调用f2(101):
void f1(int64_t);
void f2(const int64_t&);
int main()
{
f1(99);
f2(101);
}
...
pushl 0
pushl $99
call _Z2f1x // by value - pushed two halves to stack
leal -8(%ebp), %eax
movl %eax, (%esp)
movl $101, -8(%ebp)
movl $0, -4(%ebp)
call _Z2f2RKx // by const& - ugly isn't it!?!
然后必须在第一次使用之前检索被调用的函数(如果有的话)。被调用函数可以自由地缓存寄存器中读取的值,因此只需要一次。使用堆栈方法,可以随意重读该值,因此不需要为该值保留寄存器。使用指针方法,指针或64位值可能需要保存在更可预测的地方(例如,推送或另一个不太有用的寄存器),如果该寄存器需要暂时释放以用于其他一些工作,但是64位稍后需要再次使用int参数。总而言之,很难猜出哪个更快 - 可能是CPU /寄存器使用/优化/等依赖,并且不值得尝试。
pst建议的节点......
“效率”:( KISS。传递它如何通过其他所有血腥整数。 - pst
...但是,有时你会将KISS应用于模板参数并使它们全部成为const T&amp;即使有些可能适合寄存器......
答案 4 :(得分:3)
使用一点常识,
如果对象需要一个复杂的复制构造函数,它可能值得通过引用传递(说 - 很多boost的对象被设计为按值传递而不是参考,因为内部实现非常简单)有一个奇怪的我没有真正解决过,std::string
,我总是通过参考传递这个......
如果您打算修改传入的值,请使用引用
另外,PASS-BY-VALUE!
您是否存在功能参数的特定性能瓶颈?另外,不要花太多时间担心哪种方式最好通过......
通过担心如何传递int
进行优化就像在海中嬉戏一样......