通过"this->member"访问 c++ 成员类是否比隐式调用"member"更快/更慢
Is accessing c++ member class through "this->member" faster/slower than implicit call to "member"
在我们的朋友google上搜索了一下之后,我对以下几点没有一个清晰的认识。
我习惯用this->
来调用类成员。即使不需要,我也发现它更显式,因为它有助于维护一些带有大量变量的繁重算法。
当我正在研究一个应该被优化的算法时,我想知道使用this->
是否会改变运行时性能。
不,两种情况下的调用完全相同。
这没什么区别。下面是一个使用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
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
和main中的代码:
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寄存器传递。
一门语言的编译涉及到几个层次。
将member
访问为member
, this->member
, MyClass::member
等的差异…是语法上的差异。
更准确地说,这是一个名称查找的问题,以及编译器的前端如何"找到"您所引用的确切元素。因此,您可以通过更加精确来加快编译速度……虽然它不会被注意到(c++中涉及到更多耗时的任务,比如打开所有的include)。
既然(在这种情况下)你引用的是同一个元素,它应该不重要。
现在,一个有趣的类比可以用解释语言来完成。在解释型语言中,名称查找将延迟到调用行(或函数)的时刻。因此,它可能在运行时产生影响(尽管再次强调,可能并不真正明显)。
相关文章:
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 二叉搜索如何比线性搜索更快?
- push_back并插入 C++ STL 中哪个更快?
- 如何使插入排序更快?
- C++,为什么数组比矢量更快,使用更少的内存
- 哪个更快:在 1d 向量中按字符串搜索还是在 2d 向量中按向量搜索?
- 哪种方式更快?究竟发生了什么,我们没有看到什么?
- 使用 int32_t 而不是双精度运行矢量点积是否更快?
- 为什么一种算法在相同的时间复杂度下比另一种算法更快?
- C++模运算符与移位运算符,哪个更快,为什么?
- 遍历向量与数组哪个更快?
- 为什么按值传递QStringView比引用常量更快?
- 更快的C++算术运算
- 为什么C++可执行文件在与较新的libstdc++.so链接时运行得更快?
- 当我不关心顺序并且没有重复项时,更快的擦除删除成语?
- 如果要求比较器是严格的总排序,而不仅仅是严格的弱排序,C++标准算法会更快吗?
- SDL GPU 为什么将两个图像分成两个单独的循环更快?
- 有没有更快的方法可以在 std::vector 中插入元素
- 为什么酷睿i5-6600在非方阵乘法方面比酷睿i9-9960X更快?
- 通过"this->member"访问 c++ 成员类是否比隐式调用"member"更快/更慢