昨天晚上我和同事在討論一個小程式,該程式只是需要一點小邏輯而已,並不會很複雜~ 而且可以有多種寫法,整個故事如下:
該程式需要進行一些轉換的工作,條件是將「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... 那我幹嘛還花時間去想公式~ 唯一的好處就只剩下程式比較「美」罷了~ (自我感覺良好...)
最後謝謝我那位同事(匿名)陪我一起討論 ^^
