Friday, June 15, 2007

到底 import 會影響什麼?

> 請問各位高手:
> import的多少,
> 是否會影響執行效能?
> 是否儘量不要import太多class比較好?
> tks~

應該不會影響執行效能
但compile應該有影響
-----------------------------------------------------
其實三年前我有一本"Java 深度歷險",裡面就討論過這個問題,
不過好像初學者不會去看,而且好像也買不到了,所以在這裡
在解釋一次.
這個問題要分成run time和compie time兩個地方來說明:

1. run time
基本上,import的指令並不會留在byte code的資訊裡面,
因為編譯的時候,所以的類別早就被合成"全名(qualified name)",
而不是一般程式裡面我們為了方便所簡寫的類別名而已.
舉個例子來說,大家在程式裡面所寫的
System.out.println("xxxxx")
在compile的時候,早就被組合成
Java.lang.System.out.println("xxxxx")
所以import的多寡,並不會影響執行時期的效能.

2.compile time
如果以編譯器的角度來看, "import"這個關鍵字所代表的意義,
就是建立一個"名稱合成的候選名單",舉個例子來說,
如果我們打
import a.b.* ;
import x.y.* ;
...
MyClass a = new MyClass() ;
那麼編譯器將有可能最後寫入byte code時,
所合成的全名為 a.b.MyClass 或 x.y.MyClass
所以,如果我們import指令的數量越多,編譯器
在最糟的情況下,要測試到最後一個才會成功(如果一個都不成功,就是compile error了)
這是唯一會影響編譯器效能的地方.
不過一般的誤解,認為import會影響效能是因為import a.b.*
的最後一個"*"符號,因為這是一個常見的萬用字元符號,
所以一般人會有"編譯器費了很大的功夫去搜尋類別"感覺,
事實上,編譯器從來沒有因為這個"*"的符號而去進行搜尋的動作,
這個"*"對編譯器的意義是"給個機會讓你合成看看,如果成功了,那就對了!"
所以,
import a.b.MyClass ;

import a.b.*;
的差別在於,第一種的情況下,編譯器沒有選擇的餘地,只要遇到
MyClass,就一律解釋成a.b.MyClass,而第二種則是編譯器為了知道
到底類別的全名是啥,所以會嚐試地合成a.b.MyClass,
最後再配合classpath的設定,去找到真正class file的位置,
進而進行語法和語意分析. 更細微的部分就不談了,
打字打到這裡手酸了.

參考資料:
http://www.javaworld.com.tw/jute/post/view?bid=29&id=55922&sty=3

0 Comments:

Post a Comment

<< Home