昨天晚上我和同事在討論一個小程式,該程式只是需要一點小邏輯而已,並不會很複雜~ 而且可以有多種寫法,整個故事如下:
該程式需要進行一些轉換的工作,條件是將「1到12的整數,能轉換成1->12, 2->1, 3->2.... 12->11」這樣的處理,很顯然的~ 這只需要一個「if-else」判斷式即可搞定,程式如下:
if (i == 1) return 12; else return i-1;
看起來相當直覺~ 而且可讀性也還不錯~ 只是龜毛的我硬是想要用公式來解決它,解法如下:
return (i+10)%12+1;
好了,問題來了~ 以程式碼的可讀性來說前者俱備這樣的優勢,唯一可以挑剔的就是和後者相比程式碼多了點...(其實也還好 XD)
那這兩種解法哪一種執行的效率高呢?「if-else」判斷式?還是公式?
筆者寫了個Java程式來測試~ 不過得不到答案,可能是JVM的關係導致一下子解法一快~ 一下子又解法二比較快... Orz
public class Test { public static int test1(int i) { return (i + 10) % 12 + 1; } public static int test2(int i) { return (i == 1) ? 12 : i - 1; } public static void main(String[] args) { long s1 = System.nanoTime(); for (int i = 0; i < 1000000000; i++) test1(i); long e1 = System.nanoTime(); System.out.println(e1 - s1); long s2 = System.nanoTime(); for (int i = 0; i < 1000000000; i++) test2(i); long e2 = System.nanoTime(); System.out.println(e2 - s2); } }
不過可以確定的是,如果只從被編譯後的class檔所包含的opcode來看~ 用公式解的opcode數量少了一個,但是執行測試的結果不代表用公式解的效率就比較好:
public static int test1(int); Code: Stack=2, Locals=1, Args_size=1 0: iload_0 1: bipush 10 3: iadd 4: bipush 12 6: irem 7: iconst_1 8: iadd 9: ireturn public static int test2(int); Code: Stack=2, Locals=1, Args_size=1 0: iload_0 1: iconst_1 2: if_icmpne 10 5: bipush 12 7: goto 13 10: iload_0 11: iconst_1 12: isub 13: ireturn
既然如此,筆者就改用C來測試看看:
#include <stdio.h> #include <time.h> int test1(int i) { return (i+10)%12+1; } int test2(int i) { return (i==1)?12:i-1; } int main(void) { clock_t start_tick, end_tick; double elapsed; start_tick = clock(); for(int i = 0 ; i < 1000000000 ; i++) test1(i); end_tick = clock(); elapsed = (double) (end_tick - start_tick) / CLOCKS_PER_SEC; printf("test1 taken:=%f\n",elapsed); start_tick = clock(); for(int i = 0 ; i < 1000000000 ; i++) test2(i); end_tick = clock(); elapsed = (double) (end_tick - start_tick) / CLOCKS_PER_SEC; printf("test2 taken:=%f\n",elapsed); return 0; }
gcc -std=c99 -o test test.c
測試結果出爐:
test1 taken:=6.090000 test2 taken:=4.050000
「if-else」判斷式獲勝!! Orz... 那我幹嘛還花時間去想公式~ 唯一的好處就只剩下程式比較「美」罷了~ (自我感覺良好...)
最後謝謝我那位同事(匿名)陪我一起討論 ^^
餘數運算拖到的吧
2010-09-22 18:23:38
嗯~ 我們那時候討論也有這麼認為~ ^^
2010-09-22 19:00:11
這種題目在計算機組織就會考你,換到底層的instruction,每個instruction占多少clock cycle就可以一目了解,你的case有除法,一般這個clock cycle通比較長
2011-09-24 02:22:15
樓上的哥哥... 2點了還不睡啊! XD
2011-09-24 14:23:05