2017-07-25 54 views
3

所以,讓我們考慮有以下摘錄的情況:在迭代中放置條件語句是不好的做法嗎?

if(x = 0) 
{ 
    for(var i = 0; i < 5; ++ i) 
    { 
     //do something 
    } 
} 
else 
{ 
    for(var i = 0; i < 5; ++ i) 
    { 
     //do something different 
    } 
} 

正如你可以看到,這兩個條件通過相同的循環重複進行,但根據條件不同的動作。我的問題是,它是一個不好的做法是這樣的:

for(var i =0; i < 5; ++ i) 
{ 
    if(x = 0){ 
     // do something 
    }else{ 
     // do something else 
    } 
} 

原因是,我認爲這可能是一個不好的做法是由於這樣的事實,對於循環的每個實例,條件檢查正在對其執行,首先檢查條件,然後執行循環。我錯了嗎?

+2

Nitpick:請注意條件表達式中的「x = 0」賦值。 – doynax

+0

@doynax我提交了一個編輯,但由於某種原因它被拒絕了。 – hnefatl

+0

@hnefatl可能是因爲這會改變OP代碼的行爲。我們都知道這可能是一個錯字,但它是由OP來決定的...... –

回答

4

除非你正在編寫的代碼,必須高速運行,並超高效,去代碼的可讀性超過效率。在這種情況下,我會說第二個例子更清晰,因爲它的代碼更少,並且通常遵循一種模式。

我猜想,雖然考慮的另一個因素是,第二個例子似乎暗示x可能會改變值,而第一個例子沒有。這是值得在解釋選擇附近發表評論。

我的直覺會同意你的觀點,第一個例子會更有效率,但實際上編譯器的優化很可能會使上面的例子變得很短 - 它們在性能上可能是相同的。

下面是可以在循環中進行優化的pretty impressive list,給出一個想法,並且branch optimisation(請參閱答案)可能會在循環運行多次迭代時產生影響。

+0

如果你給出了其他例子,比如長循環或循環中的循環,那會更好。這些案例的結果會非常不同。 – ReadyFreddy

+1

@ReadyFreddy我不太瞭解編譯器優化以提供很好的示例 - 我將添加一些鏈接到似乎相關的資源,儘管這很重要。如果您可以添加示例,請隨時編輯我的答案。 – hnefatl

+0

@hnefatl:的確如此。第一種變體通常在優化速度時更爲可取,第二種變體則優化尺寸。注意,如果在關鍵代碼路徑上使用依賴於優化器的自動託管是脆弱的,因爲在一般情況下證明'x'是否可能通過別名改變或類似改變是不平常的。本地副本可能是一個有幫助的提示,但是當然它會反過來讓程序員證明'x'是恆定的。 – doynax

0

如果使用

if(x = 0) 
{ 
    for(var i = 0; i < 5; ++ i) 
    { 
     //do something 
    } 
} 
else 
{ 
    for(var i = 0; i < 5; ++ i) 
    { 
     //do something different 
    } 
} 

那麼你已經做了一個比較,並在範圍內執行任務的5次的循環。

當您使用

for(var i =0; i < 5; ++ i) 
{ 
    if(x = 0){ 
     // do something 
    }else{ 
     // do something else 
    } 
} 

然後在範圍執行任務5次的循環。除此之外,比較完成5次。

乍一看前者導致指令最少。但編譯器/解釋器可以通過一次比較來執行優化步驟。但這取決於編譯器/解釋器。如果您對編譯器/解釋器如何針對您正在編程的給定語言有很好的理解,則可以「濫用」該知識來編寫可讀代碼,並且具有良好優化的輸出。

然而,另一種選擇是使用函數工作。這種方法是如果變量x是恆定整個循環,與其它詞時纔有用:你在循環過程本身不會修改它。第一個例子就是這種情況。然而,在第二個例子中:x可以在循環,這導致在循環期間運行的是if {}else{}塊,執行兩種不同的功能改變。

備選:第一選擇一個功能,並在循環使用它。如果你有很多不同的任務要執行,它可能會更有用。事先選擇一個功能。有些編程語言允許這樣做,另一種不允許。所以這取決於語言本身。

// check which function to run 
variable runThisFunction; 
if (x = 0) runThisFunction = { // do something } 
else runThisFunction = { // do something else } 

// loop 5 times using the function 
for(var i =0; i < 5; ++ i) 
{ 
    call runThisFunction with arg i provided. 
} 
+0

值得注意的是,如果有機會「做某件事」或「做其他事情」來改變'x'的值,那麼這些並不等同。 –

+0

(這總是假設OP真的意味着'x == 0'而不是'x = 0') –

+1

@JordiNebot是真的,但是如果你看第一個例子,你可以看到他試圖選擇一個任務,然後做它5次。 Ofc在第二個例子中可能會有所不同,可以修改'x'。如果它改變了,那麼我的例子是無效的。 Gotcha編輯帖子 – KarelG

相關問題