java效能優化方案5——使用原始型別和棧

kele2014發表於2017-12-16

5、使用原始型別和棧
之前介紹了來自 jOOQ的例子中使用了大量的泛型,導致的結果是使用了 byte、 short、 int 和 long 的包裝類。但至少泛型在Java 10或者Valhalla專案中被專門化之前,不應該成為程式碼的限制。因為可以通過下面的方法來進行替換:
//儲存在堆上
Integer i = 817598;
……如果這樣寫的話:
// 儲存在棧上
int i = 817598;
在使用陣列時情況可能會變得更加糟糕:
//在堆上生成了三個物件
Integer[] i = { 1337, 424242 };
……如果這樣寫的話:
// 僅在堆上生成了一個物件
int[] i = { 1337, 424242 };
小結
當我們處於 N.O.P.E. 分支的深處時,應該極力避免使用包裝類。這樣做的壞處是給GC帶來了很大的壓力。GC將會為清除包裝類生成的物件而忙得不可開交。
所以一個有效的優化方法是使用基本資料型別、定長陣列,並用一系列分割變數來標識物件在陣列中所處的位置。
遵循LGPL協議的 trove4j 是一個Java集合類庫,它為我們提供了優於整形陣列 int[] 更好的效能實現。
例外
下面的情況對這條規則例外:因為 boolean 和 byte 型別不足以讓JDK為其提供快取方法。我們可以這樣寫:
Boolean a1 = true; // … syntax sugar for:
Boolean a2 = Boolean.valueOf(true);

Byte b1 = (byte) 123; // … syntax sugar for:
Byte b2 = Byte.valueOf((byte) 123);
其它整數基本型別也有類似情況,比如 char、short、int、long。
不要在呼叫構造方法時將這些整型基本型別自動裝箱或者呼叫 TheType.valueOf() 方法。
也不要在包裝類上呼叫構造方法,除非你想得到一個不在堆上建立的例項。
非堆儲存
當然了,如果你還想體驗下堆外函式庫的話,儘管這可能參雜著不少戰略決策,而並非最樂觀的本地方案。


相關文章