精簡程式碼技巧
11.乘法和除法使用移位操作
如:
for(val = 0;val < 100000;val += 5) {
a = val * 8;
b = val / 2;
}
用移位操作可以極大的提升效能,因為在計算機底層,對位的操作是最方便的。
可以替換為:
for(val = 0;val < 100000;val += 5) {
a = val << 3;
b = val >> 1;
}
注: 移位操作雖然方便,但是可能使程式碼不太好理解,因此需要加上相應的註釋。
12.迴圈內不要不斷建立物件引用
如:
for(int i = 0;i <= count; i++) {
Object obj = new Object();
}
這種做法會導致記憶體中有count份Object物件引用存在,count很大的話,就耗費記憶體了,可以替換為:
Object obj = null;
for(int i = 0;i <= count;i++) {
obj = new Object();
}
這樣的話,記憶體中只有一份Object物件引用,每次new Object()的時候,Object物件引用指向不同的Object而已,但是記憶體中只有一份,就可以節省很多記憶體空間了。
13.基於效率和型別檢查的考慮,應該儘可能使用array,無法確定陣列大小時才使用ArrayList。
14.儘量使用除非執行緒安全需要,否則不推薦使用Hashtable,Vector,StringBuffer,後三者由於使用同步機制而導致了效能開銷。
15.不要將陣列宣告為public static final
因為這樣毫無意義,這樣知識定義了引用為static,final,陣列的內容還是可以隨意改變的,將陣列宣告為一個public更是一個安全漏洞,這意味著整個陣列可以被外部類所改變。
16.儘量在何時的場合使用單例
使用單例可以減輕載入的負擔,縮短載入時的時間,提高載入的效率,但並不是所有的地方都適用於單例,簡單說,單例主要適用於以下三個方面:
(1) 控制資源的使用,通過執行緒同步來控制資源的併發訪問;
(2) 控制例項的產生,達到節約資源的目的;
(3) 控制資料的共享,在不建立直接關聯的條件下,讓多個不相關的程序或執行緒之間實現通訊。
17.儘量避免隨意使用靜態變數
因為當某個物件被定義為static時,gc通常是不會回收這個物件所佔有的堆記憶體的,如:
public class A {
private static B b = new B();
}
此時靜態變數b的生命週期與A類相同,如果A類不被解除安裝,那麼引用B指向的B物件會一直存在記憶體中,直到程式終止。
18.及時清除不再需要的會話
當應用伺服器需要儲存更多會話時,如果記憶體不足,作業系統會把部分資料轉移到磁盤裡,應用伺服器也可能根據MRU(最近頻繁使用的會話)演算法,把部分不活躍的會話轉存到磁盤裡,甚至可能丟擲記憶體不足的異常。如果會話要被轉存到磁碟,就必須先序列化,在大規模叢集中,對物件進行序列化代價是很大的。因此,應及時呼叫HttpSession的invalidate()方法清除會話。
19.實現RandomAccess介面的集合比如ArrayList,應當使用for迴圈而不是foreach來遍歷
JDK API對於RandomAccess介面的解釋是:實現RandomAccess介面用來表明其支援快速隨機訪問,此介面的主要目的是允許一般的演算法更改其行為,從而將其應用到隨機或連續訪問列表時能夠提供良好的效能。
實現RandomAccess介面類例項,加入是隨機訪問的,使用for迴圈比foreach效率高;如果不是隨機訪問的使用foreach效率高。
如:
if(list instanceof RandomAccess) {
for(int i = 0 ;i < list.size();i++){}
} else {
for(List li : list) {
System.out.println(li);
}
}
foreach底層實現原理就是迭代器(iterator)
20.使用同步程式碼塊代替同步方法
除非能確定整個方法都是需要進行同步的,否則儘量使用同步程式碼塊,避免對那些不需要同步的程式碼也進行同步,從而影響效率。