c – 返回std :: pair与非const引用的传递
为什么返回std :: pair或boost :: tuple比通过引用返回效率低得多?在我测试的实际代码中,通过非const引用而不是内核中的std :: pair设置数据可以将代码加速20%.
作为一个实验,我查看了三个最简单的情况,包括将两个(预定义的)整数添加到两个整数: >使用内部内联函数通过引用修改整数 使用g -c $x -Wall -Wextra -O2 -S进行编译会产生相同的汇编代码,以便按引用传递并按值返回int: __Z7getPairiRiS_: LFB19: pushq %rbp LCFI0: leal 1023(%rdi),%eax addl $31,%edi movl %eax,(%rsi) movq %rsp,%rbp LCFI1: movl %edi,(%rdx) leave ret (通过参考代码: #include <utility> inline void myGetPair(const int inp,int& a,int& b) { a = 1023 + inp; b = 31 + inp; } void getPair(const int inp,int& b) { myGetPair(inp,a,b); } 使用单独的右值: #include <utility> inline int myGetPair1(int inp) { return 1023 + inp; } inline int myGetPair2(int inp) { return 31 + inp; } void getPair(const int inp,int& b) { a = myGetPair1(inp); b = myGetPair2(inp); } ) 但是,使用std :: pair会添加五个额外的汇编语句: __Z7getPairiRiS_: LFB18: leal 31(%rdi),%eax addl $1023,%edi pushq %rbp LCFI0: salq $32,%rax movq %rsp,%rbp LCFI1: orq %rdi,%rax movq %rax,%rcx movl %eax,(%rsi) shrq $32,%rcx movl %ecx,(%rdx) leave ret 其代码几乎与前面的示例一样简单: #include <utility> inline std::pair<int,int> myGetPair(int inp) { return std::make_pair(1023 + inp,31 + inp); } void getPair(const int inp,int& b) { std::pair<int,int> result = myGetPair(inp); a = result.first; b = result.second; } 任何知道编译器内部工作原理的人都可以帮助解决这个问题吗? boost tuple page引用了元组与传递引用的性能损失,但没有一个链接的文章回答这个问题. 我更喜欢std :: pair到这些pass-by-reference语句的原因是它使得函数的意图在许多情况下更加清晰,特别是当输入其他参数以及要修改的参数时. 解决方法
我尝试使用VC 2008,使用cl.exe / c / O2 / FAs foo.cpp(即“仅编译并且不链接”,“优化速度”和“在注释中使用匹配的源代码行转储汇编输出”) ).以下是getLine()最终的结果.
“byref”版本: PUBLIC ?getPair@@YAXHAAH0@Z ; getPair ; Function compile flags: /Ogtpy ; COMDAT ?getPair@@YAXHAAH0@Z _TEXT SEGMENT _inp$= 8 ; size = 4 _a$= 12 ; size = 4 _b$= 16 ; size = 4 ?getPair@@YAXHAAH0@Z PROC ; getPair,COMDAT ; 9 : myGetPair(inp,b); mov eax,DWORD PTR _inp$[esp-4] mov edx,DWORD PTR _a$[esp-4] lea ecx,DWORD PTR [eax+1023] mov DWORD PTR [edx],ecx mov ecx,DWORD PTR _b$[esp-4] add eax,31 ; 0000001fH mov DWORD PTR [ecx],eax ; 10 : } ret 0 ?getPair@@YAXHAAH0@Z ENDP ; getPair “byval”std :: pair-returning版本: PUBLIC ?getPair@@YAXHAAH0@Z ; getPair ; Function compile flags: /Ogtpy ; COMDAT ?getPair@@YAXHAAH0@Z _TEXT SEGMENT _inp$= 8 ; size = 4 _a$= 12 ; size = 4 _b$= 16 ; size = 4 ?getPair@@YAXHAAH0@Z PROC ; getPair,COMDAT ; 8 : std::pair<int,int> result = myGetPair(inp); mov eax,DWORD PTR _inp$[esp-4] ; 9 : ; 10 : a = result.first; mov edx,ecx ; 11 : b = result.second; mov ecx,eax ; 12 : } ret 0 ?getPair@@YAXHAAH0@Z ENDP ; getPair 如您所见,实际装配是相同的;唯一的区别在于错误的名称和评论. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |