2008-08-29 95 views
5

我有一個if語句有兩個條件(由OR運算符分隔),其中一個條件覆蓋了+ 70%的情況,並且處理/執行的時間比第二個條件少得多,所以在速度利益我只想要第二個條件被處理,如果第一個條件評估爲假。如果語句條件優化

如果我訂購的條件,使第一個條件(更快的一個)出現在if語句中 - 在滿足條件並評估爲真的第二個條件是甚至處理?

if ((condition1) | (condition2)){ 
    // do this 
} 

或將我需要嵌套兩個if語句只檢查第二個條件,如果第一個計算結果爲假?

if (condition1){ 
    // do this 
}else if (condition2){ 
    // do this 
} 

我在php工作,但我認爲這可能是語言不可知的。

回答

9

對於C,C++,C#,Java和其他.NET語言,布爾表達式進行了優化,只要知道了足夠的數據,就不會評估其他任何內容。

的老把戲做混淆代碼是使用它來創建if語句,如:

a || b(); 

如果「A」是真的,「B()」永遠不會被評估,所以我們可以把它改寫成:

if(!a) 
    b(); 

和類似:

a && b(); 

將成爲

if(a) 
    b(); 

請注意,這隻適用於||。和& &運營商。兩個運營商|和&分別是或,和和,因此不是「優化」。

編輯: 正如其他人提及的,嘗試使用短路邏輯來優化代碼是很少以及花費的時間。

首先要清楚,因爲它更容易閱讀和理解。另外,如果你試圖太聰明,對條款進行簡單的重新排序可能會導致非常不同的行爲,而沒有任何明顯的原因。

二,去優化,但只有在時機和分析後。太多開發人員在不分析的情況下做過早的優化。大多數時候它完全沒用。

0

由於這是標記的語言不可知的我會鐘聲。對於Perl來說,第一個選項就足夠了,我不熟悉PHP。它從左到右進行評估,並在條件滿足時立即退出。

0

在體面的優化大多數語言前者會工作得很好。

2

我最近見過很多這類問題 - 優化到第n級。

我覺得很有道理在某些情況下:

  1. 計算條件2不是一個固定時間操作
  2. 你問嚴格的教育目的 - 你想知道如何在語言的作品,不節省3us。

在其他情況下,擔心迭代或檢查條件的「最快」方式是愚蠢的。而不是編寫需要數百萬次試驗才能看到任何可記錄(但微不足道)差異的測試,而不是集中於清晰度。

當其他人(可能是你!)在一個月或一年中拿起此代碼時,最重要的是清晰度。

在這種情況下,您的第一個示例更短,更清晰,並且不需要您重複自己。

2

根據this article PHP做短路評估,這意味着如果第一個條件得到滿足,第二個甚至沒有評估。 這是很容易也測試了(文章):

<?php 
/* ch06ex07 – shows no output because of short circuit evaluation */ 

if (true || $intVal = 5) // short circuits after true 
{ 

echo $intVal; // will be empty because the assignment never took place 
} 

?> 
3

在C,C++和Java,語句:

 
if (condition1 | condition2) { 
    ... 
} 

will evaluate both conditions every time and only be true if the entire expression is true.

The statement:


if (condition1 || condition2) { 
    ... 
} 

將評估condition2只有condition1是假的。如果condition2是一個函數或另一個帶有副作用的表達式,則區別很顯着。

然而,||案件與if/else案件之間沒有區別。

0

|是PHP中的按位運算符。確切地說,這並不意味着$a OR $b。你會想要使用雙管。是的,如前所述,PHP做短路評估。以類似的方式,如果&&子句的第一個條件評估爲false,則PHP不會評估該子句的其餘部分。

1

雖然使用短路爲優化的目的往往是矯枉過正的,但肯定還有其他令人信服的理由來使用它。一個這樣的例子(在C++)如下:

if(pObj != NULL && *pObj == "username") { 
    // Do something... 
} 

在此,短路被依靠確保pObj之前已經解除引用它分配。這比嵌套的if語句要簡潔得多。

0

VB.net有兩個精彩的表現稱爲「OrElse運算」和「AndAlso」

OrElse運算會短路本身在第一時間到達一個真實的評估和執行你想要的代碼。

If FirstName = "Luke" OrElse FirstName = "Darth" Then 
    Console.Writeline "Greetings Exalted One!" 
End If 

而且,它也會在第一次將它自身短路,而不是評估塊內的代碼。

If FirstName = "Luke" AndAlso LastName = "Skywalker" Then 
    Console.Writeline "You are the one and only." 
End If 

我覺得這兩個都有幫助。

+1

這正是什麼||和&&在大多數其他語言中分別使用。 – 2010-06-12 09:49:18

2

短路不是爲了優化。它的主要目的是避免調用不起作用的代碼,而導致可讀的測試。例如:

if (i < array.size() && array[i]==foo) ... 

請注意,如果我超出範圍並導致程序崩潰,數組[i]可能會很好地獲得訪問衝突。因此這個程序肯定取決於短路評估!

我相信這是編寫表達式的原因,這種方式比優化問題更爲常見。