while(1) 和 for( ; ; ) 的效率比较
最近在学习线程池,然后看到大佬写的线程池代码用的for( ; ; )
死循环,虽然可以这样用,但是毕竟没有while(1)
这个更直观,所以我查了下资料:这里看到
用while构造死循环时,一般会使用while(TRUE)来构造死循环;而用for来构造死循环时,则使用for(;;)来构造死循环。这两个死循环的区别是:while循环里的条件被看成表达式,因此,当用while构造死循环时,里面的TRUE实际上被看成永远为真的表达式,这种情况容易产生混淆,有些工具软件如PC-Lint就会认为出错了,因此构造死循环时,最好使用for(;;)来进行。
又看到这个
for(;;)和while(1)在早期的编译器上是有区别的,for要比while少一句判断.而在新的编译器上,2者的差别已经没有了,现在的编译器已经能作出很智能的优化了.下面是用BCB写的代码的汇编码,可以看出已经没有区别了:
有了大概的认知,我肯定不能全信,那我肯定要试试,所以我写了下面两段代码,分别在linux和windows下反编译
-
while(1)循环
#include <stdio.h> int main() { while(1) { printf("while ..\n"); sleep(1000); } }
-
反编译
-
vc2019,ISO C++14 环境
00007FF6ED551074 lea rcx, [string "for ..\n" (07FF6ED552240h)] 00007FF6ED55107B call printf(07FF6ED551010h) 00007FF6ED551080 mov ecx, 3E8h 00007FF6ED551085 call qword ptr[__imp_Sleep(07FF6ED552000h)] 00007FF6ED55108B jmp main + 4h(07FF6ED551074h)
-
linux gcc 版本 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
40057d: 55 push % rbp 40057e : 48 89 e5 mov % rsp, % rbp 400581 : bf 30 06 40 00 mov $0x400630, % edi 400586 : e8 c5 fe ff ff callq 400450 < puts@plt > 40058b : bf e8 03 00 00 mov $0x3e8, % edi 400590 : b8 00 00 00 00 mov $0x0, % eax 400595 : e8 e6 fe ff ff callq 400480 < sleep@plt > 40059a : eb e5 jmp 400581 < main + 0x4 > 40059c : 0f 1f 40 00 nopl 0x0(% rax)
-
-
for(;;)循环
#include <stdio.h> int main() { for(;;) { printf("for ..\n"); sleep(1000); } }
-
反编译
-
vc2019,ISO C++14 环境
00007FF70E401074 lea rcx, [string "while ..\n" (07FF70E402240h)] 00007FF70E40107B call printf(07FF70E401010h) 00007FF70E401080 mov ecx, 3E8h 00007FF70E401085 call qword ptr[__imp_Sleep(07FF70E402000h)] 00007FF70E40108B jmp main + 4h(07FF70E401074h)
-
linux gcc 版本 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
40057d: 55 push % rbp 40057e : 48 89 e5 mov % rsp, % rbp 400581 : bf 30 06 40 00 mov $0x400630, % edi 400586 : e8 c5 fe ff ff callq 400450 < puts@plt > 40058b : bf e8 03 00 00 mov $0x3e8, % edi 400590 : b8 00 00 00 00 mov $0x0, % eax 400595 : e8 e6 fe ff ff callq 400480 < sleep@plt > 40059a : eb e5 jmp 400581 < main + 0x4 > 40059c : 0f 1f 40 00 nopl 0x0(% rax)
-
能看到,除了打印的消息不一样,都是无条件 jmp
指令,得出结论,新版编译器不需要在乎for(;;)和while(1)循环的效率问题,编译器已经帮我们处理了