循环效率的 C++:主体与事后想法
c++ for loop efficiency: body vs. afterthought
我在leetcode上发现了一些有趣的东西,希望有人可以帮助解释原因:
我基本上是在进行合并排序,并使用快速慢速指针来查找中间指针。以下是此类代码片段的两个版本:
1. 事后更新
for (ListNode* fast=head;
fast->next && fast->next->next;
fast = fast->next->next, slow = slow->next) { }
2. 正文更新
for (ListNode* fast=head; fast->next && fast->next->next; ) {
fast = fast->next->next;
slow = slow->next;
}
为什么版本 2 比第一个更快?
编译器:g++ 4.9.2
逗号操作不太可能显着降低 for 循环的速度。
我已经制作了这两种变体并打开了反汇编(在Visual Studio 2012中),以便他们看到差异。
-
看起来像:
for (ListNode* fast = head; 0022545E mov eax,dword ptr [head] 00225461 mov dword ptr [ebp-2Ch],eax fast->next && fast->next->next; 00225464 jmp main+17Bh (022547Bh) fast = fast->next->next, slow = slow->next) { 00225466 mov eax,dword ptr [ebp-2Ch] 00225469 mov ecx,dword ptr [eax+4] 0022546C mov edx,dword ptr [ecx+4] 0022546F mov dword ptr [ebp-2Ch],edx 00225472 mov eax,dword ptr [slow] 00225475 mov ecx,dword ptr [eax+4] 00225478 mov dword ptr [slow],ecx 0022547B mov eax,dword ptr [ebp-2Ch] 0022547E cmp dword ptr [eax+4],0 00225482 je main+192h (0225492h) 00225484 mov eax,dword ptr [ebp-2Ch] 00225487 mov ecx,dword ptr [eax+4] 0022548A cmp dword ptr [ecx+4],0 0022548E je main+192h (0225492h) }
-
是:
for (ListNode* fast = head; fast->next && fast->next->next;) { 0024545E mov eax,dword ptr [head] 00245461 mov dword ptr [ebp-2Ch],eax 00245464 mov eax,dword ptr [ebp-2Ch] 00245467 cmp dword ptr [eax+4],0 0024546B je main+190h (0245490h) 0024546D mov eax,dword ptr [ebp-2Ch] 00245470 mov ecx,dword ptr [eax+4] 00245473 cmp dword ptr [ecx+4],0 00245477 je main+190h (0245490h) fast = fast->next->next; 00245479 mov eax,dword ptr [ebp-2Ch] 0024547C mov ecx,dword ptr [eax+4] 0024547F mov edx,dword ptr [ecx+4] 00245482 mov dword ptr [ebp-2Ch],edx slow = slow->next; 00245485 mov eax,dword ptr [slow] 00245488 mov ecx,dword ptr [eax+4] 0024548B mov dword ptr [slow],ecx }
区别只有一个jmp
。抱歉,但我看不到显着差异,因此性能问题可能不在这两个语句的位置。
相关文章:
- Clang 工具,用于提取给定 lambda 类型的 lambda 主体
- 我可以在构造函数的主体中转发构造吗?
- C++:如何在声明枚举类的模板类主体之外定义枚举类?
- GCC 能否优化具有相同主体的函数的代码大小?
- 构造函数主体内的本地指针C++内存泄漏
- 如何在方法主体中返回声明向量的引用?
- 调用一个小函数两次(例如在if条件和主体中)比将结果存储在局部变量中更可取
- 我可以检查初始化列表中设置的构造函数主体中的变量吗
- 如果函数是在类的主体中定义的,我是否需要在成员函数的返回类型中指定 typename?
- 重载运算符主体仅包含一个函数调用
- 具有相同主体的两个函数具有不同的名称
- 错误 C2084:函数"int main(void)"已具有主体
- C++ 没有在命名空间外部声明的类主体的类
- 调用没有主体的未实现静态方法
- 在这种情况下,我可以避免使用带有主体的纯虚函数吗?
- 在成员初始值设定项列表和构造函数主体中委派构造函数有什么区别
- 将数组传递回主体
- gcc/g 是否会生成if(false)语句的主体
- 确定功能主体中的返回类型
- 循环效率的 C++:主体与事后想法