歡迎您光臨本站 註冊首頁

Java高手經驗分享 Java性能的十一個用法

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0
Java語言習慣用語
1.循環
■ 在重要的循環里,消除循環終止判斷時的方法調用.
例如:將
for(int i=0; i<collection.size();i ){ … }
替換為…
for(int i=0; n=collection.size();i<n;i ){…}
■ 通常,把與循環index不相關的移到循環的外面
for(int i=0; terminal=x.length;i<terminal;i ){x[i] = x[i]/scaleA *scaleB;}
應該該成:
Double scale = scaleB*scaleA;for(int i=0; terminal=x.length;i<terminal;i ){x[i] = x[i]/scale ;}
2.字元串
■ 消除字元串連接
■ 創建長字元串時,總是使用StringBuffter代替String
■ 預先分配StringBuffer空間 StringBuffer sb = new StringBuffer(5000);
3.基本數據類型
■ 在重要的循環里使用基本數據類型(int型數據通常比long/double型數據更快)
■ 基本數據類型(Boolean,Integer,etc)的包裝類主要用在當傳遞的方法參數必須是一個對象的引用時(而不是一個基本數據類型)
■ 對所有的常量代數表達式使用static final修飾符
■ 使常量更容易引用(編譯器預先計算常量表達式)
4.異常
■ 異常只用於單個真正的錯誤條件 如小說520網 www.5a520.cn 拋出異常時
拋出一個異常和執行一個catch代碼塊花費是很高的(主要由於當創建一個異常時要獲得線程棧的一個快照)
只當條件真的異常時才拋出一個異常
■ 拋出異常要創建一個新的對象.
Throwable介面的構造函數調用名為fillInStackTrace()的本地(Native)方法,fillInStackTrace()方法檢查堆棧,收集調用跟蹤信息.
只要有異常被拋出,VM就必須調整調用堆棧,在處理過程中創建了一個新的對象.
異常只能用於錯誤處理,不應該用來控制程序流程.
■ 使編譯器和運行時最優化,將幾個方法調用放在一個try/catch塊中,而不是為每個方法調用實現幾個try/catch塊
try{ Some.method1(); //Difficut for java1.4 }catch(method1Exception e){ handle exception 1 // to optimize this code } try{ Some.method2(); //Difficut for java1.4 }catch(method2Exception e){ handle exception 2 // to optimize this code } try{ Some.method3(); //Difficut for java1.4 }catch(method3Exception e){ handle exception 3 // to optimize this code }
應該寫為:
try{ Some.method1(); Some.method2(); Some.method3(); //Difficut for java1.4 }catch(method1Exception e){ handle exception 1 }catch(method2Exception e){ handle exception 2 }catch(method3Exception e){ handle exception 3 }
5.基準
■ 注意,所有這些技巧會因不同的平台和虛擬機而不同
一 例如:在有些servlet容器內,通過一個OutputStream作為位元組輸出會更快


二 在其它的容器內,通過一個PrintWriter輸出字元會更快
■ 這些技巧描述的是最可移植的建議
■ 你可能需要運行一些基準來判斷在你的平台上怎麼樣是最快的
6.不用new關鍵詞創建類的實例
■用new關鍵詞創建類的實例時,構造函數鏈中的所有構造函數都會被自動調用.
但如果一個對象實現了Cloneable介面,我們可以調用它的clone()方法.clone()方法不會調用任何類構造函數.
在使用設計模式(Design Pattern)的場合,如果用Factory模式創建對象,則改用clone()方法創建新的對象實例非常簡單.
例如,下面是Factory模式的一個典型實現:
public static Credit getNewCredit() { return new Credit(); }
優化后:
private static Credit BaseCredit = new Credit(); public static Credit getNewCredit() { return (Credit) BaseCredit.clone();}
上面的思路對於數組處理同樣很有用.
7.使用非阻塞I/O
■Java版本較低的JDK不支持非阻塞I/O API.為避免I/O阻塞,一些應用採用了創建大量線程的辦法(在較好的情況下,會使用一個緩衝池).這種技術可以在許多必須支持併發I/O流的應用中見到,如Web伺服器、報價和拍賣應用等.然而,創建Java線程需要相當可觀的開銷.
JDK 1.4引入了非阻塞的I/O庫(java.nio).如果應用要求使用版本較早的JDK,在這裡有一個支持非阻塞I/O的軟體包.
8.不要重複初始化變數
■默認情況下,調用類的構造函數時, Java會把變數初始化成確定的值:所有的對象被設置成null,整數變數(byte、short、int、long)設置成0,float和 double變數設置成0.0,邏輯值設置成false.
當一個類從另一個類派生時,這一點尤其應該注意,用new關鍵詞創建一個對象時,構造函數鏈中的所有構造函數都會被自動調用.
9.盡量指定類的final修飾符
■帶有final修飾符的類是不可派生的.在Java核心API中,有許多應用final的例子,例如java.lang.String.為String類指定final防止了人們覆蓋length()方法.
另外,如果指定一個類為final,則該類所有的方法都是final.Java編譯器會尋找機會內聯(inline)所有的final方法(這和具體的編譯器實現有關).此舉能夠使性能平均提高50%.
10.盡量使用局部變數
■調用方法時傳遞的參數以及在調用中創建的臨時變數都保存在棧(Stack)中,速度較快.其他變數,如靜態變數、實例變數等,都在堆(Heap)中創建,速度較慢.另外,依賴於具體的編譯器/JVM,局部變數還可能得到進一步優化.請參見《儘可能使用堆棧變數》.
11.乘法和除法
■考慮下面的代碼:


for (val = 0; val < 100000; val =5) { alterX = val * 8; myResult = val * 2; }
優化后:
for (val = 0; val < 100000; val = 5) { alterX = val 《 3; myResult = val 《 1; }
修改後的代碼不再做乘以8的操作,而是改用等價的左移3位操作,每左移1位相當於乘以2.相應地,右移1位操作相當於除以2.值得一提的是,雖然移位操作速度快,但可能使代碼比較難於理解,最好加上一些註釋.


[火星人 ] Java高手經驗分享 Java性能的十一個用法已經有399次圍觀

http://coctec.com/docs/java/show-post-59911.html