java效能優化(乾貨)--降低時間與空間消耗
阿新 • • 發佈:2019-02-11
前言
我們提出一些通過降低時間與間消耗來改進java程式執行時間的建議。 這裡沒有什麼魔術的技巧,僅僅在避免常見問題上提出建議。
1 降低時間消耗
1.1 基本程式碼優化
不要期望java編譯器(例如javac或jikes)去做許多聰明的優化。 因為java有比較嚴格的語句次序和執行緒語義,所以相對於C或者Fortran等比較少嚴格定義的語言, 要安全的提高java程式的效能,編譯器能做的事情很有限。但是你可以改進你自己的java原始碼,來做到這點。
注: 理解為語句上的次序
注: 嚴格定義指語法上限制
- 把迴圈不變數的計算移到迴圈之外。例如,避免重複計算一個for迴圈裡的邊界,像這樣:
1
|
|
應該僅計算一次迴圈邊界,然後把結果賦值給一個本地變數,像這樣:
1
|
|
- 不要重複計算同樣的子表示式:
1 2 |
|
應該計運算元表示式一次,然後把結果賦值給一個變數,並且重用這個變數:
1 2 3 |
|
- 每一次陣列訪問需要一個索引檢查,所以降低資料訪問次數是值得的。另外,通常java編譯器不能 自動優化多維陣列的索引。例如,內迴圈(j)的每次迭代,重新計算索引rowsum[i]和arr的第一維索引arr[i]:
1 |
|
相反,在外迴圈的每次迭代中只計算一次這些索引值:
1 2 3 4 5 6 7 8 |
|
注意的是,初始化中arri = arr[i]並沒有拷貝陣列的第i行;它僅僅把陣列引用(4個位元組)賦給arri.
- 把不變屬性宣告為final static,讓編譯器可以inline它們和預計算不變表示式。
- 把不變的變數宣告為final,讓編譯器可以inline它們和不變表示式。
- 如果可以的話,把一個長的if-else-if鏈替換為switch;它要快很多.
- 加入一個長的if-else-if鏈不能替換為switch(例如因為它檢測一個String), 假如它執行很多次的話,通常值得替換為一個final static的HashMap,或類似的結構。
- 使用’聰明的’C慣用法沒有什麼用(除了讓程式碼更隱晦),例如一個while迴圈的迴圈條件中進行所有的計算工作:
1 2 3 4 |
|