switch 比 if/else 效率更高?
在很多人的概念里,switch 的執行效率是比 if/else 高的。依據就是很多人以為的,if/else 是用了多次比較判斷,而 switch 是用的跳轉表一次跳轉。事實真的是這樣嗎?
考察以下幾個例子,switch 改成 if/else 之后效率會變化很多嗎?
【例1】
int x = GetIntValue();
switch(x) {
case 1: // do something
case 2: // do something
case 3: // do something
// ...
case 32: // do something
default: // do something
}
【例2】
int x = GetIntValue();
switch(x) {
case 1: // do something
case 12: // do something
case 123: // do something
// ...
case 123456789: // do something
default: // do something
}
【例3】
int x = GetIntValue();
switch(x) {
case 1: // do something
case 2: // do something
case 3: // do something
default: // do something
}
注意,跳轉表其實是一個數組,並不是python/javascript “表驅動” 編程的那種哈希表。
對於第一個例子,case范圍集中,用跳轉表確實比用if/else 判斷要好一些,編譯器只需要使用一個大小為32的跳轉表,跳轉前判斷一下是否在表范圍內,然后查表一次就可以了。
對於第二種情況,case非常分散,如果使用跳轉表的話,表要開多大、跳轉要幾次?如果我們希望仍然跳轉一次,那么表的大小就要開的很大。實際上,編譯器在面臨這種情況時的處理方式是 —— 存入一個小的數組然后使用二分查找的方式來進行查詢,實際查表 logN 次。
對於最后這種情況,case很少,編譯器會直接轉化成if/else來判斷,沒有區別。
有人曾經做過測試 為什么很多程序員不用 switch,而是大量的 if...else if ...? - 詹姆斯.通的回答 - 知乎,100個case以內,if/else 和 switch 性能差別很小,超過 450 個case 才出現顯著差距。實際上,現代編譯器已經足夠聰明,會根據case的情況,自動選擇合適的方式來實現 switch,也會主動優化 if/else 的實現邏輯。
所以,我們編程的時候,不要着眼於這種小細節上的過度優化,處理好代碼邏輯,然后選擇相信編譯器就好了。畢竟,代碼99%的時間是用來給人讀的,只有1%的時間是給機器來運行的。