回答
讓我們找到它了:
void Test1() {
while (GetTickCount()) {
printf("Hello World Test1");
break;
}
}
void Test2() {
if (GetTickCount()) {
printf("Hello World Test2");
}
}
void main() {
Test1(); Test2();
}
編譯使用VC 2013年11月CTP的釋放與全面優化:
CPU Disasm
Address Hex dump Command Comments
012A12A0 /$ FF15 00302A01 CALL DWORD PTR DS:[<&KERNEL32.GetTickCou ; [KERNEL32.GetTickCount
012A12A6 |. 85C0 TEST EAX,EAX
012A12A8 |. 74 0E JZ SHORT 012A12B8
012A12AA |. 68 8C312A01 PUSH OFFSET 012A318C ; ASCII "Hello World Test1"
012A12AF |. FF15 64302A01 CALL DWORD PTR DS:[<&MSVCR120.printf>]
012A12B5 |. 83C4 04 ADD ESP,4
012A12B8 |> FF15 00302A01 CALL DWORD PTR DS:[<&KERNEL32.GetTickCou ; [KERNEL32.GetTickCount
012A12BE |. 85C0 TEST EAX,EAX
012A12C0 |. 74 0E JZ SHORT 012A12D0
012A12C2 |. 68 A0312A01 PUSH OFFSET 012A31A0 ; ASCII "Hello World Test2"
012A12C7 |. FF15 64302A01 CALL DWORD PTR DS:[<&MSVCR120.printf>]
012A12CD |. 83C4 04 ADD ESP,4
012A12D0 |> 33C0 XOR EAX,EAX
012A12D2 \. C3 RETN
正如你可以看到相同的代碼由VC編譯器生成。這雖然不是這種情況,如果禁止優化:
Test1的
CPU Disasm
Address Hex dump Command Comments
00F91630 /$ 55 PUSH EBP ; Playground.Test1(void)
00F91631 |. 8BEC MOV EBP,ESP
00F91633 |> FF15 0030F900 /CALL DWORD PTR DS:[<&KERNEL32.GetTickCo ; [KERNEL32.GetTickCount
00F91639 |. 85C0 |TEST EAX,EAX
00F9163B |. 74 12 |JZ SHORT 00F9164F
00F9163D |. 68 9C31F900 |PUSH OFFSET 00F9319C ; ASCII "Hello World Test1"
00F91642 |. FF15 6430F900 |CALL DWORD PTR DS:[<&MSVCR120.printf>]
00F91648 |. 83C4 04 |ADD ESP,4
00F9164B |. EB 02 |JMP SHORT 00F9164F
00F9164D |.^ EB E4 \JMP SHORT 00F91633
00F9164F |> 5D POP EBP
00F91650 \. C3 RETN
的Test2
CPU Disasm
Address Hex dump Command Comments
00F91660 /$ 55 PUSH EBP ; Playground.Test2(void)
00F91661 |. 8BEC MOV EBP,ESP
00F91663 |. FF15 0030F900 CALL DWORD PTR DS:[<&KERNEL32.GetTickCou ; [KERNEL32.GetTickCount
00F91669 |. 85C0 TEST EAX,EAX
00F9166B |. 74 0E JZ SHORT 00F9167B
00F9166D |. 68 B031F900 PUSH OFFSET 00F931B0 ; ASCII "Hello World Test2"
00F91672 |. FF15 6430F900 CALL DWORD PTR DS:[<&MSVCR120.printf>]
00F91678 |. 83C4 04 ADD ESP,4
00F9167B |> 5D POP EBP
00F9167C \. C3 RETN
正如你可以清楚地看到它們之間略有差別:
如果條件得不到滿足,他們的行爲完全一樣的(從而以相同的速度執行)
如果條件滿足,在
Test1
我們必須執行多一個跳躍(00F9164B
-JMP SHORT 00F9164F
)
=>Test2
從理論上講,如果代碼編譯時沒有進行優化,速度會更快,因爲編譯器會輸出一個真實的循環,用於Test1
。
這是不成熟的優化嗎? 絕對!
在彙編程序中輸出代碼並查看它是否與編譯器相同(更有可能的是,編譯器將對邏輯上相同的機器代碼進行優化)。幾乎總是編寫可讀和可維護的代碼比擔心諸如此類的細節更重要。隨着現代編譯器能夠優化這種簡單的情況,除了以最可讀的方式編寫代碼之外,沒有什麼理由做任何事情了,在這種情況下,我認爲將代碼編寫爲if
語句表明您的意圖向您的其他讀者代碼遠遠好於while
+ break
的組合。
邏輯上它們是相同的。編譯器可能會寫出相同的代碼。
您應該專注於代碼的清晰度,而不是考慮在昏迷的希望中編寫混淆代碼,以使代碼更快。
while(x){
//stuff
break;
}
如果您只對給定條件執行一次操作,上面的代碼似乎不合理。這就是爲什麼如果在這種情況下聲明更可取!至於速度差異,我真的懷疑其中一個的重要優勢。在地點的使用while循環的if語句是可怕的:
if(condition)
{
// do stuff
}
else if(another_condition)
{
// do stuff
}
else
{
// do stuff
}
這裏是一個使用while循環等價的:
while(condition)
{
// do stuff
break;
}
while(!condition && another_condition)
{
// do stuff
break;
}
while(!condition && !another_condition)
{
// do stuff
break;
}
做你的團隊一個忙,讓你的代碼可讀性:-)
這是一樣的。雖然在理論上,while()增加了一個jmp
比if if
爲什麼這樣?這個額外的跳躍在哪裏? –
@DavidHeffernan'break'後,如果編譯器沒有優化,它仍然需要跳轉到條件。雖然它將永遠不會被執行,因爲'break' –
編譯器只會在它是垃圾時才寫出它。如果你關心性能,爲什麼你會使用不做優化的垃圾編譯器? –
如果在第一次迭代中斷開while循環,則while循環將充當if語句。
但是你不應該爲此目的使用while循環,因爲它的目的是循環。
因此,以下可能會給出相同的結果,因爲for是被C預處理器修改爲一段時間。儘管......其他人對清晰度的評價
for(;x;){
//stuff
break;
}
如果你沒有回答這個問題,那麼請把它作爲評論。謝謝。 –
- 1. 突破到別的PHP
- 2. 區別,如果,如果(JAVA)
- 3. 如何「突破」dispatch_apply()?
- 4. 如何突破doseq?
- 5. 如何突破Cfoutput
- 6. 如何突破groovy'eachFileMatch()'
- 7. Firefox的過渡突破時
- 8. 如果和如果存在的區別
- 9. CSS如何突破線時長數據
- 10. 時區或時間衝突
- 11. GWT - 突破iframe
- 12. JSTL突破
- 13. jQuery突破錶
- 14. HHVM突破NotFoundHttpException
- 15. 突破jQtouch?
- 16. 突破_.filter()
- 17. 將突破
- 18. 突破.each()
- 19. FooterWrap突破框
- 20. 如何突破$。每個
- 21. Sencha:如何突破Ext.each
- 22. 如何突破inner * ngFor?
- 23. 如何突破Java中
- 24. 如何突破功能?
- 25. 如何突破@providesModule緩存
- 26. AWS登錄:Client.Timeout突破,同時等待頭
- 27. 垂直對齊圖像,同時突破容器
- 28. 泊塢窗錯誤在Windows 2016「Client.Timeout突破,同時等待頭」
- 29. 從外環突破,同時通過內環
- 30. 如何同時突出顯示地圖上的多個區域
獲取有關C++的入門書! – Nawaz
@Nawaz我想你無法在介紹性書籍 – Vider7CC
中發現我懷疑有人生氣。如果你確實對此感興趣,那麼實際測量它並檢查你自己是否真的沒有想到這一點是令人驚訝的。或者閱讀更多關於C++的內容。 – BartoszKP