c – 左值引用是否与左值引用具有相同的开销?
考虑这个例子:
#include <utility> // runtime dominated by argument passing template <class T> void foo(T t) {} int main() { int i(0); foo<int>(i); // fast -- int is scalar type foo<int&>(i); // slow -- lvalue reference overhead foo<int&&>(std::move(i)); // ??? } foo< int&&>(i)和foo< int>(i)一样快,还是像foo< int&>(i)那样涉及指针开销? 编辑:正如所建议的,运行g -S给了我相同的51行汇编文件foo< int>(i)和foo< int&>(i),但foo< int&&>(std :: move(i))产生了71行汇编代码(看起来差异来自std :: move). 编辑:感谢那些推荐具有不同优化级别的g -S的人 – 使用-O3(以及制作foo noinline),我能够获得看起来像xaxxon’s solution的输出. 解决方法
在您的具体情况下,它们可能都是一样的.来自godbolt与gcc -O3的结果代码是
https://godbolt.org/g/XQJ3Z4:
#include <utility> // runtime dominated by argument passing template <class T> int foo(T t) { return t;} int main() { int i{0}; volatile int j; j = foo<int>(i); // fast -- int is scalar type j = foo<int&>(i); // slow -- lvalue reference overhead j = foo<int&&>(std::move(i)); // ??? } 是: mov dword ptr [rsp - 4],0 // foo<int>(i); mov dword ptr [rsp - 4],0 // foo<int&>(i); mov dword ptr [rsp - 4],0 // foo<int&&>(std::move(i)); xor eax,eax ret volatile int使得编译器无法优化掉所有代码,因为它会知道调用的结果被丢弃,整个程序将优化为空. 但是,如果你强制函数不被内联,那么事情会改变一点int __attribute __((noinline))foo(T t){return t;}: int foo<int>(int): # @int foo<int>(int) mov eax,edi ret int foo<int&>(int&): # @int foo<int&>(int&) mov eax,dword ptr [rdi] ret int foo<int&&>(int&&): # @int foo<int&&>(int&&) mov eax,dword ptr [rdi] ret 上图:https://godbolt.org/g/pbZ1BT 对于这样的问题,学会爱https://godbolt.org和https://quick-bench.com/(快速工作台要求你学习如何正确使用谷歌测试) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |