標籤:android開發 java 最佳化 效能
由於考試的原因,好長時間都沒能來寫博文了(什麼時候出的CSDN-markdown編輯器),今天就代碼最佳化方面來寫一篇博文,主要是講Java。
優秀代碼具備的品質:
1.簡練
2.可讀性強
3.模組化
4.層次性
5.設計良好
花些時間設計你的程式,因為思考的代價要小於調試。
6.高效
7.清晰
清晰是優秀代碼的基本。
常見的編程規範:
1.基本要求
*程式結構清晰,簡單易懂,單個函數的程式行數最好不超過100行。
*盡量使用標準的函數和公用函數。
*不要隨意的定義全域變數,盡量使用局部變數。
*使用括弧以避免二義性。
2.可讀性的要求
*可讀性第一,效率第二。
*保持注釋與代碼完全一致。
*每個來源程式檔案,都有標頭檔說明。
*每個函數,都有函數頭說明。
*主要變數定義或引用時,注意能反應其含義。
*常量定義有相應注釋說明。
*利用縮排來顯示程式的邏輯結構,縮排量一致並以Tab鍵為單位。
3.結構化要求
*避免從迴圈引出多個出口。
*函數只有一個出口。
*不使用條件賦值語句。
*不要輕易用條件分支去替換邏輯運算式。
4.正確性與容錯性要求。
*程式首先是正確,其次是優美。
*改一個錯誤時可能產生新的錯誤,因此在修改前首先考慮對其他程式的影響。
*對所有的使用者輸入,必須進行合法性的檢查。
*不要比較浮點數的相等。如:
10.0*0.1==1.0
5.可重用行要求
*重複使用的完成相對獨立功能的演算法或代碼應抽象為公用控制項或類。
*公用控制項或類應考慮物件導向思想,減少外界聯絡,考慮獨立性或封裝性
上面說了那麼多條條框框,有點疲憊了吧,那麼下面就貼近代碼來進行講解吧。
(1)盡量指定類的final修飾符。帶有final修飾符的類是不可派生的,也就是不能被繼承
。Java編譯器會尋找機會內聯所有的final方法。此舉能夠使效能平均提高50%。
(2)盡量重用對象。特別是String對象的使用,出現字串串連情況時應用StringBuffer代替。
(3)盡量使用局部變數。調用方法時傳遞的參數以及在調用中建立的臨時變數都儲存在棧中,易於訪問。其他變數,如:靜態變數,都在最終建立,訪問速度較慢。
(4)在Java+Oracle的應用系統開發中,Java中內嵌的SQL語句盡量使用大寫的形式,以減輕Oracle解析器的解析負擔。
(5)Java編程過程中,進行資料庫連接、I/O流操作時務必小心,在使用完畢後,及時關閉以釋放資源。
(6)JVM的GC機制。JVM回收垃圾的條件:對象不再被引用;然而,JVM的G並非十分地機制,即使對象滿足了記憶體回收的條件也不一定會被立即回收。所以,建議在使用完對象後,手動設定成null。
(7)在使用同步機制時,應盡量使用方法同步代替代碼塊同步。
(8)盡量減少對變數的重複計算。
列如:
for (int i = 0; i < list.size(); i++) {}
應替換為:
for (int i = 0, size = list.size(); i < size; i++) {}(9)盡量採用lazy loading(延時載入)的策略,在需要的時候才開始建立。
列如:
String str = "1111";if (i == 1) {list.add(str);}應替換為:
if (i == 1) {String str = "1111";list.add(str);}
(10)不要在迴圈中使用Try/Catch語句,應把其放置在最外層。
(11)使用一個合適的容量值來初始化StringBuffer。當使用預設的建構函式來建立StringBuffer對象時,StringBuffer的容量被初始化問你16個字元。當StringBuffer達到最大值時,它會將自身容量增加到當前的2倍在加二。由於String達到它的最大容量,它必須建立一個新的字元數組,將原來的字元複製一遍到新建立的字元數組。
(12)合理地使用Java類java.util.Vector。
由於Vector中各個元素之間不能含有“空隙”。刪除除如最後一個元素之外的任意其他元素都會導致被刪除元素之後的元素向前移動。
示:
for (int i = 0; i < 10000; i++) {v.remove(0);}
與下面的代碼相比,上面的代碼要慢的多。
for (int i = 0; i < 10000; i++) {v.remove(v.size()-1);}從Vector類型的對象中刪除所有元素的最好方法:
v.removeAllElements();
下面說說Vector類的對象v中含有字串“123456”,對“123456”進行刪除操作。
示:
String s = "123456";int i = v.indexOf(s);if (i != -1) {v.remove(s);}此段代碼在效能上是不利的,因為indexOF()方法對v進行了順序搜尋,而remove()方法也進行了順序搜尋。
改進後:
String s = "123456";int i = v.indexOf(s);if (i != -1) {v.remove(i);}改進後代碼避免了第二次搜尋。remove()方法中給出待刪除元素的精確索引位置。
最好的實現這個功能:
String s = "123456";v.remove(s);
關於size()方法,上面(8)說明了使用方法,至於為什麼,給出如下代碼:
//假如size =100000for (int i =0;i<v.size();i++) {}由於size()中有100000個元素,每次迴圈後都會重新計算一下size的大小,所以要調用100000次v.size()。
(13)當複製大量資料時,使用
System.arraycopy();
(14)不用new關鍵詞建立類的執行個體。
用new關鍵詞建立類的執行個體時,建構函式鏈中的所有建構函式都會被自動調用。但如果一個對象實現了Cloneable介面,我們可以調用它的clone()方法。clone()方法不會調用任何類建構函式。
在使用設計模式的場合,如果用Factory模式建立對象,則改用clone()方法建立新的對象執行個體非常的簡單。例如,下面是Factory模式的一個典型實現。
public static Test getNewTest(){return new Test();}
使用clone()方法:
private static Test test = new Test();public static Test getNewTest() throws CloneNotSupportedException{return (Test) test.clone();}
(15)乘法和除法。用移位操作替代乘法可以極大地提高效能。
示:
for (int i = 0; i < 100000; i+=5) {a = i * 8;b = i * 2;}修改後:
for (int i = 0; i < 100000; i+=5) {a = i <<3;b = i <<1;}每左移1位相當於乘以2,每右移1位相當於除以2。
(16)不要將數組聲明:public static final
(17)盡量使用HashMap和ArrayList,除非必要,否則不推薦使用HashTable和Vector,後者由於使用同步機制,而導致了效能的開銷。
至此此博文接近尾聲了。最後提一點在Android開發中java代碼的最佳化。
在Android開發中,儘可能避免使用內在的Get、Set方法。
在Android編程中,虛方法的調用會產生很多代價,比執行個體屬性查詢的代價還要多。我們應該在外部調用時使用Get和Set函數,但是在內部調用時,我們應該直接調用。
代碼最佳化:學學Java看看Android