if-else和三目運算子 ? : 的對比

拉布發表於2020-07-10

今天的地鐵思考讓我想起一個之前學C語言的時候一直沒有驗證的事情:既生瑜何生亮?

  • 平時寫程式碼的時候,似乎並沒有太多的關注我應該選用什麼條件判斷語句,感覺判斷條件或者兩條支路語句複雜就本能地if-else。
    遇到一些數值,字元的按條件賦值輸出,就感覺if-else與這些簡短語句氣質不符,於是就用了三目運算子,使程式碼更簡潔舒服。那麼為什麼有了if-else還要用?:呢,只是為了程式碼更簡潔嗎,還是有什麼不為人知的祕密[/嘿嘿]
  • 我打算稍稍探尋一下,從兩個方面來聊聊:效率和三目運算子的表示式特性

關於執行效率

  • 我在網上一直沒有找到可靠的說辭或指南,有的說三目運算子效率高,還有的說一樣的,所以我來測測(測試環境可能由於我的電腦效能,給定引數原因,不能得出確切的結論,僅供參考)
    - if-else
    public static void main(String[] args) {
        int num=1000;
        System.out.println("if-else 執行時間:");
        long totalTime=0L;
        for (int i = 1; i <=10 ; i++) {
            long startTime = System.nanoTime();
            if (num>500&&num%3!=0&&num/10==100){
                num=1001;
            }else{
                num=0;
            }
            long endTime = System.nanoTime();
            long result = endTime - startTime;
            totalTime+=result;
            System.out.println("第"+i+"次: " + result + " 納秒");
        }
        System.out.println("平均時間為:"+totalTime/10+"納秒");
}
  • 執行結果:

  • 三目運算子 ? :

public static void main(String[] args) {
        int num = 1000;
        System.out.println("? : 執行時間:");
        long totalTime = 0L;
        for (int i = 1; i <= 10; i++) {
            long startTime = System.nanoTime();
            num = num > 500 && num % 3 != 0 && num / 10 == 100 ? 1001 : 0;
            long endTime = System.nanoTime();
            long result = endTime - startTime;
            totalTime += result;
            System.out.println("第" + i + "次: " + result + " 納秒");
        }
        System.out.println("平均時間為:" + totalTime / 10 + "納秒");
}
  • 執行結果:
  • 從結論上來看,平均執行時間並沒有太大差距,畢竟這裡是以納秒為單位,所以,暫且以為 ? :僅僅是簡化程式碼的吧
  • 如果哪位大佬有專業的權威的見解,請一定來“拍一拍”我,讓我的石頭落下。


表示式特性(BNP : binary numeric promotion)

  • 二進位制數值提升
    - 在三目運算子中的第二和第三表示式的型別依據數值範圍大的那個,將一個小數值的型別範圍擴大,比如16位提升到32位,32位到64位,直觀一點就是short提升到int,int提升到long,不同型別之間也可以提升,但是不一定是往兩個其中的一個走,也有short和char,最終表示式是int的情況。

  • 舉幾個栗子就比較清楚了
    - 1,引數是int和byte,但是整個表示式的型別卻是int

    - 2,引數:int,char  表示式型別:int
    ![](https://img2020.cnblogs.com/blog/1900950/202007/1900950-20200710014429504-750530626.png)
    
    - 3,引數:short,char  表示式型別:int
    ![](https://img2020.cnblogs.com/blog/1900950/202007/1900950-20200710014735763-1827387039.png)
    
    - 4,引數:int,float  表示式型別:float (如果位元組數相同,會提升到浮點數)
    ![](https://img2020.cnblogs.com/blog/1900950/202007/1900950-20200710014805770-916117378.png)
    
    
    - 5,引數:int,long   表示式型別:long
    ![](https://img2020.cnblogs.com/blog/1900950/202007/1900950-20200710014944472-1952654095.png)
    
    
    - 6,引數:long,double  表示式型別:double (如果位元組數相同,會提升到浮點數)
    ![](https://img2020.cnblogs.com/blog/1900950/202007/1900950-20200710015004272-720659868.png)
    
    - 7,同上的包裝類,包裝類在運算時自動拆箱,和基本資料型別結果無異
    ![](https://img2020.cnblogs.com/blog/1900950/202007/1900950-20200710015130391-625091652.png)
    
    - 8,更具體一點
    ```
    int number = 1000;
    System.out.println(number<0?10.0:9);
    ```
    console:
    ![](https://img2020.cnblogs.com/blog/1900950/202007/1900950-20200710020252217-1846785275.png)
    

總的來看,if-else和三目運算子並沒有在今天分出勝負,我們依然可以按照之前的習慣寫程式碼,只是讓我們之後寫程式碼的不用再猶豫和糾結用什麼好,不用再想起他們倆之間的糾葛。在實際生產環境中按照各自團隊規範來就好。這些也是最近才發現的,雖然感覺很少用到,但這不是目的。我們遇到的東西那麼多,不會每樣都能用到你的程式裡,只是為了在下次遇到此類問題Bug時,能夠遊刃有餘,這就是我們程式設計師鴨,突然感覺這篇文章啥也沒做,但是卻也不是啥也沒做,哈哈奇怪咧。


至此,若有紕漏,望各位不吝賜教

相關文章