1. 先把焦點放到設計、數據結構和算法上。
2. 不要依賴編譯期優化技術。
編譯期優化是指:在調試階段,把編譯優化給關閉掉,當調試完畢後,再打開編譯優化讓編譯優化來選擇最便捷的代碼,這樣程序運行性能就很好。Java編譯器對產生優化後的bytecode不是很啓作用。
3. 理解運行期(runtime)代碼優化技術
4. 要使字符串拼接結合,請儘量使用StringBuffer,而不是String。
String表示建立後的對象,其字符序列不能夠再被修改了。
StringBuffer表示建立後的對象,其中的字符序列的值是可以變化的。
5. 將創建對象的成本降到最小。
創建對象所有做到事情,順序如下:
1.從heap 之中分配內存,用以存放全部的instance 變量以及這個對象連同其superclasses 的實現專屆數據(implementation-specific data)。所謂[實現專屬數據]包括指向“class and method data”的指針。
2.對象的instance 變量被初始化爲其相應的缺省值。
3.調用most derived class(最深層派生類)的構造函數(constructor)。構造函數做的第一件事就是調用superclass 的構造函數。這個程序一直反覆持續到java.1ang.object 構造函數被調用爲止。一定要記住,java.1ang.object 是一切Java 對象的base class。
4.在構造函數本體執行之前,所有instance 變量的初始值設定(initializers) 和初始化區段(initialization blocks)先獲得執行,然後才執行構造函數本體。於是base class 的構造函數最先執行,most derived class 的構造函數最後執行。這使得任何class 的構造函數都能放心大膽地使用其任何superclasses 的instance 變量。
創建對象的過程,舉例如下:
public class Light {
private int val;
private boolean hasData = true;
public Light(int a) {
val = a;
}
public static void main(String[] args) {
Light lgt = new Light(2);
}
}
Light 對象的建立步驟如下:
1.從heap 分配內存,用來存放Light class 的instance 變量,以及一份[實現專屬數據]。
2.此class 的instance 變量val 和hasDate,被初始化爲相應缺省值。Val 被賦值爲0,這是Int 的缺省值,hasDate 被韌始化爲缺省值fa1se。
3.調用Light 構造函數,傳入數值5。
4.調用Light 構造函數調用其superclass(本例爲j ava.1ang.object)的構造函數。
5.一旦java.1ang.object 構造函數返回,Light構造函數執行其instance 變量的初值設定工作。此時將hasData 賦值爲true。
6.將val 賦值爲5,而後Light 構造函數結束。
7.object reference lgt 指向head 中剛剛建立完成的Light對象。
以下class特徵會增加創建對象的成本:
1. 構造函數含有大量代碼;
2. 內含數量衆多的對象;
3. 繼承層次太深。
6. 慎防未用上的對象
在需要的時候才創建對象。
7.將同步化(synchronization)降至最低
一般情況下,請不要使用synchronized,因爲會降低性能。如果不得已的話,請優先將synchronized加在函數上,然後再考慮是否加在函數內部。因爲如果你在函數本體中使用synchronized,就會產生操作代碼monitorenter 和Moniterexit 的bytecode,以及爲了處理異常而附加的代碼。
8. 儘可能使用stack變量。
9. 使用static、final 和private 函數以促成inlining(內聯)。以函數體替換掉函數調用,性能會增加。一般是小型函數被促成inlining。
10. instance 變量的初始化一次就好.對象的instance變量的默認初始化,在構造方法執行前已經執行力次,所以不需要造次執行。只有class 的static 變量和instance 變量纔有缺省值,局部變量是沒有缺省值。
11.使用原生態數據類型代碼更快更小。
不要使用Enumeration 或Iterator 來遍歷Vector。Java提供了以下方式來獲取變量vector中的元素:
a.Interaor遍歷器
b. ListInterator遍歷器(只針對List的)
c. Enumeration(枚舉器)
d. Get函數
12.使用System.arraycopy來複制數組. System.arraycopy()是以本機函數(native method)實現的,因此它的執行速度更快。
13.優先使用數組,然後再考慮使用Vector和ArrayList。Vector和ArrayList底層都是以數組來實現的,而Vector調用的時候都是同步的,並且都要調用其他函數,所以在數組、Vector、ArrayList這三者中,Vector效率最慢。
14.儘可能複用對象。
15.使用緩式評估(延遲求值,lazy evaluation),是一項與語言無關的技術,它會延緩計算,直到不能再拖延爲止。工作的推遲當然不會帶來性能的提升,但如果被推遲的計算後來不再需要,從而不需執行的話,性能就提升了。也就是說免除了非必要的工作。
16. 以手工的方式將代碼優化。Javap –c 便可以反編譯.class文件。
Java –c 類(去掉了.class後綴)> test.txt(存儲文件),將會產生bytecode。
17. 編譯爲本機代碼。將java 源碼編譯爲目標平臺上的本機二進制碼(native binary code)。。這種做法並不是把java 源碼編譯爲中介的bytecode 形式.而是直接編譯爲本機機器指令(native machine instructions)。這樣做的好處在於,你不再需要爲[運行期間將bytecode 轉換爲native code 付出額外代價,因而往往獲得更快捷的代碼。缺點是通常會丟失[平臺可移植性]——儘管這或許不是你在意的。面對這個問題,至少有一種解決方案,既不會失去平臺可移植性,又享有本機二進制碼(native binary code)在執行速度上的優勢。