簡體   English   中英

為什么 if 語句中的表達式順序很重要

[英]Why is order of expressions in if statement important

假設我有一個IF條件:

if (A || B) 
    ∧
    |
    |
   left
{ 
   // do something  
}

現在假設AB更有可能獲得真值,我為什么要關心左邊的是哪個?

如果我將它們都放在IF括號中,那么我知道(作為代碼的程序員)雙方都需要。

問題是,我的教授在他的講義上寫道,我應該把“更有可能得到真值的變量”放在左邊。

有人可以解釋一下好處嗎? 好吧,我把它放在左邊……我得到了什么? 運行 ?

它不僅僅是選擇左側最可能的條件。 您還可以在左側設置一個安全防護裝置,這意味着您只能有一個訂單。 考慮

if (s == null || s.length() == 0) // if the String is null or empty.

您不能在此處交換順序,因為第一個條件可以保護第二個條件免於拋出 NPE。

同樣你可以有

if (s != null && s.length() > 0) // if the String is not empty

選擇最可能為真的原因為|| &&或 false 是微優化,以避免在第二個表達式中計算的成本。 這是否會轉化為可衡量的性能差異是值得商榷的。

我把它放在左邊......我得到了什么? 運行時間

因為|| C++ 中的運算符使用短路求值
即:僅當A被評估為false時才評估B

但是,請注意,在 C++ 中,短路評估是針對“內置”數據類型而不是自定義數據類型保證的。

根據javadoc

&& 和 || 運算符對兩個布爾表達式執行條件與和條件或運算。 這些運算符表現出“短路”行為,這意味着僅在需要時才評估第二個操作數

因此,如果 true 語句按順序排在最前面,它會在運行時短路第二個操作數。

如果左側的表達式為真,則無需計算右側的表達式,因此可以在運行時對其進行優化。 這是一種稱為短路的技術。 因此,通過將更可能為真的表達式放在左側,我們可以期望我們的程序比相反的表現更好。

您應該首先放置更有可能為真的條件,因為這會導致 if 語句短路。 這意味着它不會評估 if 語句的其余部分,因為它已經知道答案為真。 這使代碼更有效率。

當您的 if 語句評估昂貴的東西時,這尤其有用:

if(doExpensiveCheck1() || doExpensiveCheck2()) { }

在這種情況下,由於支票很昂貴,首先放置最有可能的支票對您有利。

在許多情況下,除了微小的性能改進外,沒有實際區別。 如果您的檢查是非常昂貴的函數調用(不太可能),或者您需要按順序檢查事物,那么這會變得有用。 舉例來說,你想檢查某物的屬性並首先檢查它是否為 nil,你可能會執行以下操作:

If (a != nil && a.attribute == valid) {}

是的,您正在獲得運行時間,一次操作似乎並不多,但您必須記住,操作將重復數百萬次

為什么在一個足夠的情況下執行兩個評估是邏輯

在運行時 if(a||b) 將首先測試 a,如果 a 為真,則不會浪費時間測試 b,因此編譯器將提前 1 次執行。 因此,如果 a 比 b 更可能為真,則此測試也可能會切斷 1 條線。 一行中未執行的總行數很少,但如果語句嵌套在某種循環中(for、while、recession 或數據庫相關查詢),則它會很大。 例如,假設我們有 100 萬分鍾來測試數據庫中的數據,每條記錄 1 分鍾(條件 A 為 30 秒,條件 B 為 30 秒)。 讓 A 有 80% 的機會是真的,B 有 20% 的機會是真的。 如果你把A放在第一位需要的總時間是600-000小時,如果你把B放在第一位需要900-000小時。如果先測試A[(0,8*1百萬小時)*0,5分鍾+(0,2*1百萬小時) *1min]===6000-000hrs :如果 B 被首先測試 [(0,2*1百萬小時)*0,5mins+(0,2*1百萬小時)*1min]===9000-000hrs。 但是,您會注意到,如果 A 變為真的概率更接近 B 的概率,則差異就不那么顯着了。

public class Main
{
    public static void main(String[] args) {
        System.out.println("Hello World");
        Integer a = null;
        Integer b = 3;
        Integer c = 5;

        if(a != null && a == 2){
            System.out.println("both");
        }else{
            System.out.println("false");
        }
    }
}

你好世界
錯誤的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM