switch與ifelse的效率問題


switch...case與if...else的根本區別在於,switch...case會生成一個跳轉表來指示實際的case分支的地址,而這個跳轉表的索引號與switch變量的值是相等的。從而,switch...case不用像if...else那樣遍歷條件分支直到命中條件,而只需訪問對應索引號的表項從而到達定位分支的目的。

具體地說,switch...case會生成一份大小(表項數)為最大case常量+1的跳表,程序首先判斷switch變量是否大於最大case 常量,若大於,則跳到default分支處理;否則取得索引號為switch變量大小的跳表項的地址(即跳表的起始地址+表項大小*索引號),程序接着跳到此地址執行,到此完成了分支的跳轉。


由此看來,switch有點以空間換時間的意思,而事實上也的確如此。


1.當分支較多時,當時用switch的效率是很高的。因為switch是隨機訪問的,就是確定了選擇值之后直接跳轉到那個特定的分支,但是if。。else是遍歷所以得可能值,知道找到符合條件的分支。如此看來,switch的效率確實比ifelse要高的多。
2.由上面的匯編代碼可知道,switch...case占用較多的代碼空間,因為它要生成跳表,特別是當case常量分布范圍很大但實際有效值又比較少的情況,switch...case的空間利用率將變得很低。
3.switch...case只能處理case為常量的情況,對非常量的情況是無能為力的。例如 if (a > 1 && a < 100),是無法使用switch...case來處理的。所以,switch只能是在常量選擇分支時比ifelse效率高,但是ifelse能應用於更多的場合,ifelse比較靈活。

 

1.switch用來根據一個整型值進行多路分支,並且編譯器可以對多路分支進行優化
2.switch-case只將表達式計算一次,然后將表達式的值與每個case的值比較,進而選
  擇執行哪一個case的語句塊
3.if..else 的判斷條件范圍較廣,每條語句基本上獨立的,每次判斷時都要條件加載
  一次。
所以在多路分支時用switch比if..else if .. else結構要效率高。


首先要看一個問題,if 語句適用范圍比較廣,只要是 boolean 表達式都可以用 if 判斷;而 switch 只能對基本類型進行數值比較。兩者的可比性就僅限在兩個基本類型比較的范圍內。
說到基本類型的數值比較,那當然要有兩個數。然后重點來了——
if 語句每一句都是獨立的,看下面的語句:
if (a == 1) ...
else if (a == 2) ...
這樣 a 要被讀入寄存器兩次,1 和 2 分別被讀入寄存器一次。於是你是否發現其實 a 讀兩次是有點多余的,在你全部比較完之前只需要一次讀入寄存器就行了,其余都是額外開銷。但是 if 語句必須每次都把里面的兩個數從內存拿出來讀到寄存器,它不知道你其實比較的是同一個 a。
於是 switch case 就出來了,把上面的改成 switch case 版本:
switch (a) {
        case 0:
                break;
        case 1:
}

3.
因為當虛擬機讀到switch的時候將所有的判斷數據都加載在內存中了,而if是邊判斷邊加載,所以就慢一些,
一般如果判斷數據不多,而且是byte,short,int或是char類型的時候一般用switch,那樣效率比較高.

Java中(C不知道):如果case中的值比較稀疏,則使用lookupswitch:

可以看到其中的
 3: lookupswitch{ //4
3: 44;
20: 55;
50: 66;
100: 77;
default: 85 }
這個就要挨着查表確定跳轉位置了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM