switch與ifelse的效率問題

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

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


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


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 }
這個就要挨着查表肯定跳轉位置了。ci

相關文章
相關標籤/搜索