好的,在我的系统上测试了这个。完全优化后,编译器只设置了 count = 50,没有问任何问题。如果没有优化,第二个版本通常会稍微快一点,但完全可以忽略不计。
反汇编:两个循环都有完全相同的代码,除了比较一次是 100,一次是 50(我稍微增加了一些数字以允许更长的执行时间)
for(int i = 0; i< 100; i++) {
00F9140B mov dword ptr [i],0
00F91412 jmp main+5Dh (0F9141Dh)
00F91414 mov eax,dword ptr [i]
00F91417 add eax,1
00F9141A mov dword ptr [i],eax
00F9141D cmp dword ptr [i],64h
00F91421 jge main+88h (0F91448h)
for(int j = 0; j< 50; j++)
00F91423 mov dword ptr [j],0
00F9142A jmp main+75h (0F91435h)
00F9142C mov eax,dword ptr [j]
00F9142F add eax,1
00F91432 mov dword ptr [j],eax
00F91435 cmp dword ptr [j],32h
00F91439 jge main+86h (0F91446h)
{
count++;
00F9143B mov eax,dword ptr [count]
00F9143E add eax,1
00F91441 mov dword ptr [count],eax
}
00F91444 jmp main+6Ch (0F9142Ch)
}
00F91446 jmp main+54h (0F91414h)
外面的大循环,里面的小循环,里面的小循环,外面的大循环之间的唯一区别是你必须多久做一次跳跃
00F91439 jge main+86h (0F91446h)
to
00F91446 jmp main+54h (0F91414h)
以及循环变量的初始化:
00F91423 mov dword ptr [j],0
00F9142A jmp main+75h (0F91435h)
对于每个新循环,同时跳过以下部分。
00F9142C mov eax,dword ptr [j]
00F9142F add eax,1
00F91432 mov dword ptr [j],eax
内循环每次迭代的附加命令:mov、add、mov,但没有 mov / jmp
初始化每个内部循环的附加命令:mov、jmp,更常见的是让 JGE 为真。
因此,如果您运行内循环 50 次,那么 JGE 只会实现 50 次,因此在那里进行 50 次跳跃,而当内循环运行 100 次时,您将必须跳跃 100 次。这是代码中唯一的区别。在这种情况下,几乎没有什么区别,而且大多数情况下,您会遇到内存访问问题,这会导致比循环排序更慢的事情。唯一的例外:如果您知道可以正确排序循环以避免分支预测。因此,有两件事值得以一种或另一种方式订购您的循环:
- 内存访问
-分支预测
对于其他一切,影响完全可以忽略不计。