前言:
優化代碼,一個很重要的課題。可能有些人覺得沒用,一些細小的地方有什么好修改的,改與不改對代碼的運行效率有什么影響呢?這個問題我是真么考慮的,好比人吃飯,吃一粒米,沒用,但是一萬,十萬呢,這樣的效率就很可觀了。
代碼優化的目標是:
1.減小代碼體積;
2.提高代碼運行效率。
具體方法:
1.盡量指定類,方法的final修飾符
帶有final的修飾符的類是不可派生的。在java核心API中,有許多應用final的例子,例如:java.long. String,整個類都是final的。為類指定final修飾符可以讓類不可被繼承,為方法指定final修飾符可以讓方法不被重寫。如果指定了一個類為final,則該類所有的方法都是final的。
java編譯器會尋找機會內聯所有的final方法,內聯對於提升java運行效率作用重大,大概能使性能提升50%。
內聯:通常是用來消除調用函數時所需要的時間。
2.盡量復用對象
特別是String對象,出現字符串連接時應該使用StringBuffer /StringBuilder代替。由於java虛擬機不僅要花時間生成對象,以后可能還需要對這些對象進行垃圾回收和處理,因此,生成過多對象會給程序的性能帶來很大影響。
3.盡可能使用局部變量
調用方法是傳遞的參數以及在調用中創建的臨時變量都保存在棧中,相對速度比較快。其他變量如,靜態變量,實例變量等,都在堆中創建,速度較慢。另外,棧中創建的變量,隨着方法的運行結束,這些內容就消失了,不需要額外的垃圾回收。
4.及時關閉流
java編程過程中,進行的數據庫連接,I/O流等操作時務必當心,在使用完畢后,應及時關閉流以釋放資源。因為這些大對象的操作會造成系統大的開銷,會大大影響程序運行效率。
5.盡量減少對變量的重復計算
明確概念,對方法的調用,即使方法中只有一條語句,也是要加載的。包括創建堆棧。
調用方法時保護現場,方法結束時恢復現場等。如:
for(int i=0;i<list.size();i++){
}
可以替換為:
for(int i=0,length=list.size(); i<length;i++){
}
這樣,如果list.size()里的數據有很多時(如2000000左右),會減少很多性能消耗。
6.盡量使用懶加載策略,即在需要時才創建
如:
String str = "aaa";
if(i == 1) {
list.add(str);
}
可以替換為:
if(i == 1) {
String str = "aaa";
list.add(str);
}
7.慎用異常
異常對性能不利。拋出異常首先要創建一個新的對象,Throwable接口的構造函數調用名為filllnStackTrace()的本地同步方法,filllnStackTrace()方法檢查堆棧,收集調用跟蹤信息。
只要有異常被拋出,java虛擬機就必須調整調用堆棧,因為在處理過程中創建了一個新的對象。異常只能用於錯誤處理,不應該用來控制流程程序。
8.不要在循環中使用try···catch···,應該把它放到最外層。
9.如果能估計到待添加的內容長度,為底層以數組方式實現的集合,工具類指定初始長度。
比如ArrayList、LinkedList、StringBuilder、StringBuffer、HashMap、HashSet等等,
以StringBuilder為例:
(1) StringBuilder() //默認分配16個字符空間
(2) StringBuilder(int size) //默認分配size個字符空間
(3) StringBuilder(String str) //默認分配16個字符+str.length()個空間
可以通過類(不僅僅是StringBuilder)來設定它的初始化容量,這樣可以明顯提升性能。
比如StringBuilder吧,length表示當前的StringBuilder能保持的字符數量。因為當StringBuilder達到最大容量的時候,它會將自身容量加到當前的2倍在加2,無論何時,只要StringBuilder達到它的最大容量值,它就會創建一個新的字符數組然后將舊的字符數組里面的內容拷貝到新數組里是一個十分耗時的工作。
比如,一個字符數組大概要放5000個字符而不指定長度,最接近5000的2次冪是4096,那么:
(1) 在4096的基礎上,在申請8194+2個大小的新數組,加起來相當於共申請了12292的內存空間,如果一開始就指定長度5000或5500的話,就能節省一倍的空間。
(2) 把原來的4096個字符拷貝到新的字符數組中,這樣不僅浪費內存又降低代碼運行效率。 所以,給底層以數組實現的集合、工具類設置一個合理的初始值是不會有錯的。但是,注意,向HashMap這種以數組+鏈表實現的集合,別把初始值大小和你預估的大小設置的一樣,因為一個table上連接一個對象的概率幾乎為0。建議初始大小值設為2的N此冪,如果預估是2000個元素,設置成 new HashMap(128)、new HashMap(256)都可以。
10.當復制大量數據時,使用System.arraycopy()命令。
喜歡的小伙伴們可以搜索我們個人的微信公眾號“程序員的成長之路”點擊關注或掃描下方二維碼