標籤:代碼最佳化 35 條 10-20
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 = 1; 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、盡量使用HashMap、ArrayList、StringBuilder,除非安全執行緒需要,否則不推薦使用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、及時清除不再需要的會話
為了清除不再活動的會話,許多應用伺服器都有預設的會話逾時時間,一般為30分鐘。當應用伺服器需要儲存更多的會話時,如果記憶體不足,那麼作業系統 會把部分資料轉移到磁碟,應用伺服器也可能根據MRU(最近最頻繁使用)演算法把部分不活躍的會話轉儲到磁碟,甚至可能拋出記憶體不足的異常。如果會話要被轉 儲到磁碟,那麼必須要先被序列化,在大規模叢集中,對對象進行序列化的代價是很昂貴的。因此,當會話不再需要時,應當及時調用HttpSession的 invalidate()方法清除會話。
19、實現RandomAccess介面的集合比如ArrayList,應當使用最普通的for迴圈而不是foreach迴圈來遍曆
這是JDK推薦給使用者的。JDK API對於RandomAccess介面的解釋是:實現RandomAccess介面用來表明其支援快速隨機訪問,此介面的主要目的是允許一般的演算法更改 其行為,從而將其應用到隨機或連續訪問列表時能提供良好的效能。實際經驗表明,實現RandomAccess介面的類執行個體,假如是隨機訪問的,使用普通 for迴圈效率將高於使用foreach迴圈;反過來,如果是順序訪問的,則使用Iterator會效率更高。可以使用類似如下的代碼作判斷:
if (list instanceof RandomAccess){ for (int i = 0; i < list.size(); i++){}}else{ Iterator<?> iterator = list.iterable(); while (iterator.hasNext()){iterator.next() }}
foreach迴圈的底層實現原理就是迭代器Iterator,參見Java文法糖1:可變長度參數以及foreach迴圈原理。所以後半句”反過來,如果是順序訪問的,則使用Iterator會效率更高”的意思就是順序訪問的那些類執行個體,使用foreach迴圈去遍曆。
20、使用同步代碼塊替代同步方法
這點在多線程模組中的synchronized鎖方法塊一文中已經講得很清楚了,除非能確定一整個方法都是需要進行同步的,否則盡量使用同步代碼塊,避免對那些不需要進行同步的代碼也進行了同步,影響了代碼執行效率。
本文出自 “龍光祥的blog” 部落格,請務必保留此出處http://18073491002lgx.blog.51cto.com/12044386/1876609
35 個 Java 代碼效能最佳化總結 10-20