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