最佳无限循环

6

11
优化的无限循环不是个矛盾吗? - fire.eagle
4
当真?看一下编译器输出。 - Ed S.
精确重复:https://dev59.com/YXNA5IYBdhLWcg3wn_fD - Nick T
我猜测这要么是while(1),要么更可能它们是同样的。如果你好奇,为什么不写一个快速测试程序来亲自验证呢? - Ultimate Gobblement
@Stephen:我很好奇想听更多关于病态编译器的事情…… - FrustratedWithFormsDesigner
显示剩余4条评论
6个回答

52

我更喜欢使用for(;;),因为它不测试任何东西,从语义上讲这才是你的意思。如果1为真,反复测试没有多大意义。然而,任何专业的C程序员都应该能够立即识别两种习惯用法。

就实际性能而言,它们之间应该没有区别。编译器会优化掉测试。

我尝试测试两种方式以查看哪个更快,但它们都还没有完成。


25
也许再等一会儿...? - FrustratedWithFormsDesigner
1
请密切关注此事并告知我们。 ;) - Bill the Lizard
15
仅翻译最后一句话即可。 - Eli Bendersky
3
如果你想滥用预处理器,我认为“while(true)”语义上是正确的,或者可以使用“for(ever)”。 - Kobi

19

在任何正常的编译器中,两者应该没有任何区别。比如说,这里是LLVM-clang针对while (1) {}使用-O3标志生成的代码:

    .file   "test.c"
    .text
    .globl  main
    .align  16, 0x90
    .type   main,@function
main:
    pushl   %ebp
    movl    %esp, %ebp
    .align  16, 0x90
.LBB0_1:
    jmp .LBB0_1

注意 jmp .LBB0_1 的部分,它是实际的无限循环。对于 for (;;) 这种类型,它生成 完全相同的代码

你也可以尝试使用其他编译器来玩一下,但最好停止担心它。


好的,我也必须尝试一下使用 gcc

    .file   "test.c"
    .text
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
.L2:
    jmp .L2

是的,我也尝试了在gcc下使用while(1)和for(;;),但没有任何区别。 - iSegFault
使用Clang而不是GCC,加一分。 - user142019

4

我认为两者都不是更加优化的,因为两者都无法在任何可测量的时间内无限循环。

是否真的可能以更高效的方式达到无限大?


8
真相:Jon Skeet 可以在三秒半内执行一个无限循环。 - Michael Myers
@mmyers:我以为那是查克·诺里斯? - FrustratedWithFormsDesigner
1
通过删除一行代码,他可以将其优化为在0秒内运行。 - Will A
1
@沮丧:Jon Skeet 是新的 Chuck Norris。 - Eli Bendersky
1
@Frustrated:http://meta.stackexchange.com/questions/9134/jon-skeet-facts/9199#9199 - Michael Myers
1
实际上,无法以更高效或更低效的方式达到无限大,但可以以更快或更慢的速度进行运算;2^n永远不会像log(n)一样达到无限大,但是天哪,log(n)需要更长的时间!(当然,它们都趋向于无限大,随着n趋近于无穷大,但这就是整个分析领域的所在之处;指数击败幂次方击败对数等等。) - Savara

2

理论上,一个完全天真的编译器可以将文本 '1' 存储在二进制文件中(浪费空间),并检查每次迭代是否等于 0(浪费时间和更多空间)。

然而,在现实中,即使没有进行任何优化,编译器仍会将它们都简化为相同的结果。它们也可能会发出警告,因为这可能表明存在逻辑错误。例如,while 的参数可能在其他地方定义,而您可能没有意识到它是常量。


1

同样的事情。编译器会将其翻译为单个JMP指令。


0

这是我的观点(没有进行研究):

当我逐步调试代码时,对于for循环,第一次需要跳转到所有三个部分,然后在其余的迭代中只需要跳转两个部分。然而,while循环只有一个部分。这只是一个想法。


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