第一步計算最大公約數,如2,4,6,8為2,100,150,200為50,最大公約數記為x把case的數值全部除以x,最小的記為min,最大的記為max如果max-min數值不大,就可以用來最佳化。搞一個數組,max-min,記為n,全部初始化為default處理地址。然後case數值除以最大公約數x-min為陣列下標,裡面存放該case處理地址,即彙編指令jump的地址。這些過程是編譯階段的,最後直接生成一個數組,然後case就最佳化為一個jump指令了。如果max-min很大是不是就沒最佳化空間了呢?也不一定,看編譯器如何處理,比如1,2,3,4,5,999這種情況也是很常見的,上述方式失敗之後可以去掉最大值,去掉最小值重新測試,或者用二分法,分為2部分重新測試。無論怎麼複雜的測試,都是在編譯中實現的,編譯最佳化是c語言一大魅力回覆 陳君陌 :沒有最佳化空間是不是就是ifelseifelse是高階語言,編譯器直接處理彙編,應該是用條件更快,那x86來說(其他彙編指令沒研究),有個指令是結果為0跳轉或者不為0跳轉,比如case項有1,2,5,9,彙編指令可能是這樣mov eax,[esi];case val的值dec eax;減一jz addr1;為0跳轉到case1處理dec eaxjz addr2sub eax,3jz addr5sub eax,4jz addr,9處理default這裡為啥用減一跟減法操作,這個也是最佳化的結果,對於暫存器操作,是非常快的,最基礎的翻譯應該是這樣有塊記憶體,存放有1,2,5,9這4個數字然後分別取這4個數字到暫存器,然後一個個判斷,這樣的編譯只能稱為翻譯,效率是非常低的,比上述的要慢3,4倍對於不同的ifelse,編譯出來的彙編也不一定相同的比如if(--i),if(i--),為啥儘量推薦前者,前者指令更快更少mov eax,[ebp+4];存放i的堆疊dec eax;dec只需要一個機器週期,是最快的指令jz addr判斷成功的地方if(i--)mov eax,[ebp+4]test eax;類似i+0jnz addr判斷失敗地址,不為0跳轉dec eax然後處理成功部分。因此前者少了一個test指令。對於開發人員來說,可以說跟ifelse一樣,編譯器把ifelse看成很多不同情況。
每次判定都能決定解在兩個區間中的哪一個。比如順序表二分查詢
對於[m,n]只要判定(m+n)/2的元素與待查詢元素即可確定要查詢的在哪個子區間裡
第一步計算最大公約數,如2,4,6,8為2,100,150,200為50,最大公約數記為x把case的數值全部除以x,最小的記為min,最大的記為max如果max-min數值不大,就可以用來最佳化。搞一個數組,max-min,記為n,全部初始化為default處理地址。然後case數值除以最大公約數x-min為陣列下標,裡面存放該case處理地址,即彙編指令jump的地址。這些過程是編譯階段的,最後直接生成一個數組,然後case就最佳化為一個jump指令了。如果max-min很大是不是就沒最佳化空間了呢?也不一定,看編譯器如何處理,比如1,2,3,4,5,999這種情況也是很常見的,上述方式失敗之後可以去掉最大值,去掉最小值重新測試,或者用二分法,分為2部分重新測試。無論怎麼複雜的測試,都是在編譯中實現的,編譯最佳化是c語言一大魅力回覆 陳君陌 :沒有最佳化空間是不是就是ifelseifelse是高階語言,編譯器直接處理彙編,應該是用條件更快,那x86來說(其他彙編指令沒研究),有個指令是結果為0跳轉或者不為0跳轉,比如case項有1,2,5,9,彙編指令可能是這樣mov eax,[esi];case val的值dec eax;減一jz addr1;為0跳轉到case1處理dec eaxjz addr2sub eax,3jz addr5sub eax,4jz addr,9處理default這裡為啥用減一跟減法操作,這個也是最佳化的結果,對於暫存器操作,是非常快的,最基礎的翻譯應該是這樣有塊記憶體,存放有1,2,5,9這4個數字然後分別取這4個數字到暫存器,然後一個個判斷,這樣的編譯只能稱為翻譯,效率是非常低的,比上述的要慢3,4倍對於不同的ifelse,編譯出來的彙編也不一定相同的比如if(--i),if(i--),為啥儘量推薦前者,前者指令更快更少mov eax,[ebp+4];存放i的堆疊dec eax;dec只需要一個機器週期,是最快的指令jz addr判斷成功的地方if(i--)mov eax,[ebp+4]test eax;類似i+0jnz addr判斷失敗地址,不為0跳轉dec eax然後處理成功部分。因此前者少了一個test指令。對於開發人員來說,可以說跟ifelse一樣,編譯器把ifelse看成很多不同情況。