while和for死循环效率比较

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)循环的效率问题,编译器已经帮我们处理了

posted @ 2021-03-30 10:34  做个奇怪的人  阅读(1204)  评论(0编辑  收藏  举报