C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了c – 返回std :: pair与非const引用的传递大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
为什么返回std :: pair或boost :: tuple比通过引用返回效率低得多?在我测试的实际代码中,通过非const引用而不是内核中的std :: pair设置数据可以将代码加速20%.

作为一个实验,我查看了三个最简单的情况,包括将两个(预定义的)整数添加到两个整数:

>使用内部内联函数通过引用修改整数
>使用两个内部内联函数按值返回整数
>使用内部内联函数回复制到结果的std :: pair.

使用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

如您所见,实际装配是相同的;唯一的区别在于错误名称评论.

大佬总结

以上是大佬教程为你收集整理的c – 返回std :: pair与非const引用的传递全部内容,希望文章能够帮你解决c – 返回std :: pair与非const引用的传递所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。