通过“this-> member”访问c ++成员类比隐式调用“member”更快/更慢

时间:2011-10-26 08:50:03

标签: c++ optimization this

在对我们的朋友谷歌进行一些搜索之后,我无法清楚地了解以下几点。

我习惯用this->来调用班级成员。即使不需要,我发现它更明确,因为它有助于维护一些重量级的算法和大量的变量。

当我正在研究一个应该被优化的算法时,我想知道使用this->是否会改变运行时性能。

是吗?

4 个答案:

答案 0 :(得分:14)

不,两种情况下的通话完全相同。

答案 1 :(得分:10)

它没有任何区别。这是GCC的演示。来源是简单的类,但为了清楚起见,我已将这篇文章限制在差异之内。

% diff -s with-this.cpp without-this.cpp
7c7
<         this->x = 5;
---
>         x = 5;

% g++ -c with-this.cpp without-this.cpp  

% diff -s with-this.o without-this.o   
Files with-this.o and without-this.o are identical

答案 2 :(得分:4)

zennehoy和这里的汇编代码(由Microsoft C ++编译器生成)为一个简单的测试类提供了答案:

class C
{
    int n;
public:
    void boo(){n = 1;}
    void goo(){this->n = 2;}
};

int main()
{
   C c;
   c.boo();
   c.goo();

       return 0;
}

Visual Studio中的反汇编窗口显示两个函数的汇编代码相同:

class C
{
    int n;
public:
    void boo(){n = 1;}
001B2F80 55                   push        ebp  
001B2F81 8B EC                mov         ebp,esp  
001B2F83 81 EC CC 00 00 00    sub         esp,0CCh  
001B2F89 53                   push        ebx  
001B2F8A 56                   push        esi  
001B2F8B 57                   push        edi  
001B2F8C 51                   push        ecx  
001B2F8D 8D BD 34 FF FF FF    lea         edi,[ebp-0CCh]  
001B2F93 B9 33 00 00 00       mov         ecx,33h  
001B2F98 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
001B2F9D F3 AB                rep stos    dword ptr es:[edi]  
001B2F9F 59                   pop         ecx  
001B2FA0 89 4D F8             mov         dword ptr [ebp-8],ecx  
001B2FA3 8B 45 F8             mov         eax,dword ptr [this]  
001B2FA6 C7 00 01 00 00 00    mov         dword ptr [eax],1  
001B2FAC 5F                   pop         edi  
001B2FAD 5E                   pop         esi  
001B2FAE 5B                   pop         ebx  
001B2FAF 8B E5                mov         esp,ebp  
001B2FB1 5D                   pop         ebp  
001B2FB2 C3                   ret  
...
--- ..\main.cpp -----------------------------
void goo(){this->n = 2;}
001B2FC0 55                   push        ebp  
001B2FC1 8B EC                mov         ebp,esp  
001B2FC3 81 EC CC 00 00 00    sub         esp,0CCh  
001B2FC9 53                   push        ebx  
001B2FCA 56                   push        esi  
001B2FCB 57                   push        edi  
001B2FCC 51                   push        ecx  
001B2FCD 8D BD 34 FF FF FF    lea         edi,[ebp-0CCh]  
001B2FD3 B9 33 00 00 00       mov         ecx,33h  
001B2FD8 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
001B2FDD F3 AB                rep stos    dword ptr es:[edi]  
001B2FDF 59                   pop         ecx  
001B2FE0 89 4D F8             mov         dword ptr [ebp-8],ecx  
001B2FE3 8B 45 F8             mov         eax,dword ptr [this]  
001B2FE6 C7 00 02 00 00 00    mov         dword ptr [eax],2  
001B2FEC 5F                   pop         edi  
001B2FED 5E                   pop         esi  
001B2FEE 5B                   pop         ebx  
001B2FEF 8B E5                mov         esp,ebp  
001B2FF1 5D                   pop         ebp  
001B2FF2 C3                   ret  

主要代码:

    C c;
    c.boo();
    001B2F0E 8D 4D F8             lea         ecx,[c]  
    001B2F11 E8 00 E4 FF FF       call        C::boo (1B1316h)  
    c.goo();
    001B2F16 8D 4D F8             lea         ecx,[c]  
    001B2F19 E8 29 E5 FF FF       call        C::goo (1B1447h)  

Microsoft编译器默认使用__thiscall调用约定进行类成员调用,this指针通过ECX寄存器传递。

答案 3 :(得分:1)

编译语言涉及多个层次。

访问member memberthis->memberMyClass::member等等之间的差异是一种语法差异。

更确切地说,这是名称查找的问题,以及编译器的前端如何“找到”您所指的确切元素。因此,您可以通过更精确地加速编译...虽然它不会引起注意(C ++中涉及更多耗时的任务,比如打开所有这些包括)。

由于(在这种情况下)你指的是同一个元素,无关紧要。


现在,可以使用解释语言完成一个有趣的并行。在解释语言中,名称查找将延迟到调用行(或函数)的时刻。因此,它可能会在运行时产生影响(尽管可能再一次,可能不是很明显)。