哪个更快:while(1) 还是 while(2)?

616

这是一位高级经理问的面试题。

哪一个更快?

while(1) {
    // Some code
}
while(2) {
    //Some code
}

我说两者的执行速度相同,因为while语句内的表达式最终应该会评估为truefalse。在这种情况下,两者都评估为true,并且while循环条件内没有额外的条件指令。因此,两者的执行速度相同,我更喜欢while(1)

但面试官自信地说: “检查一下你的基础知识。while(1)while(2)更快。” (他并不是在测试我的自信心)

这是真的吗?

另请参阅:如果不是这样,为什么人们使用“for(;;)”?


216
一款还算不错的编译器会将这两种形式都优化成无操作。 - user1864610
72
在优化编译中,每当出现“while(n), n != 0”或“for(;;)”时,都会被翻译成带有标签的汇编无限循环,并在结尾处使用“goto”。这段代码与原始代码完全相同,性能也相同。 - Alex F
66
毫不奇怪,对股票进行优化后,两个片段都会出现 0x100000f90: jmp 0x100000f90(地址显然会有所变化)。面试官可能在寻找一个寄存器测试或简单标记跳转之间权衡。这个问题和他们的推测都很无聊。 - WhozCraig
54
面试官的问题与 http://dilbert.com/strips/comic/1995-11-17/ 相似 - 你会遇到某个人,无论他们的言论有多么愚蠢,他们都真心相信自己说的话。只需从以下选项中选择一个:深呼吸,发誓,笑,哭或以上几种的组合 :) - GMasucci
3
@Mike W: 一个人可能会想,编译器应该做什么:将代码翻译为停机语句,还是考虑循环在无限时间后退出并优化掉无限延迟? - user1196549
显示剩余15条评论
23个回答

0

显然的答案是:如所发布的,两个代码片段都将运行一个同样繁忙的无限循环,这使得程序变得无限缓慢。

虽然将C关键字重新定义为宏在技术上具有未定义的行为,但这是我能想到的使任何一个代码片段变得快速的唯一方法:您可以在2个代码片段上方添加此行:

#define while(x) sleep(x);

这确实会使得while(1)while(2)快一倍(或慢一半)。


0

由于寻找答案的人们希望最快的循环,我会回答两者同样编译成相同的汇编代码,正如其他答案中所述。然而,您可以建议面试官使用'loop unrolling';do {} while loop代替while循环。

注意:您需要确保循环至少始终运行一次

循环内部应该有一个跳出条件。

此外,对于这种类型的循环,我个人更喜欢使用do {} while(42),因为除了0以外的任何整数都能完成任务。


他为什么建议使用do{}while循环?while(1)(或while(2))也能实现同样的功能。 - Catsunami
使用do while循环可以减少一次额外的跳转,从而提高性能。当然,前提是您知道循环至少会执行一次。 - Antonin GAVREL

-4
我所能想到while(2)会变慢的唯一原因是:
  1. 代码将循环优化为
  2. cmp eax,2

  3. 当减法发生时,您实际上是在执行以下操作:
  4. a. 00000000 - 00000010 cmp eax,2

    而不是

    b. 00000000 - 00000001 cmp eax,1

cmp 仅设置标志位而不设置结果。 因此,在最低有效位上,我们可以通过 b 知道是否需要借位。 而对于 a ,您必须执行两次减法才能借位。


15
无论哪种情况,cmp都需要1个 CPU 周期。 - UncleKing
8
这段代码是错误的。正确的代码会将数字2或1加载到eax寄存器中,然后将eax与0进行比较。 - gnasher729

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接