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)循環的效率問題,編譯器已經幫我們處理了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM