程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> Java性能設計

Java性能設計

編輯:JAVA編程入門知識

  很多程序員在一開始並不注重性能的設計,只有當系統交付運行時,才 發現問題並且開始解決這一問題,但往往這只能拯救一點點。性能的治理應該一開始 就被整合到設計和開發當中去。
  
  最普遍的問題就是臨時對象大量經常的創建,這為性能埋下隱患。
  
  性能的問題來自很多原因,最輕易解決的可能是:你選擇了不好的算法來進行計算,如 用冒泡法來排序巨量數據,或者你每次使用數據時都要反復計算一次,這應該使用Cache。
  
  你能很輕易的使用工具(如Borland的Optimizeit)或壓力測試發現這些問題, 一旦發現,就能夠立即被糾正,但是很多Java的性能問題隱藏得更深,難於修改源碼就能糾正,如程序組件的接口設計。
  
  現在我們倡導面向對象的組件可復用設計,無疑這樣設計的優點是巨大的, 但是也要注重到對性能的影響。
  
  一個java性能設計原則是,避免不必要的對象創建,對象的創建是非常耗時的, 所以你要避免不必要的臨時或過多的對象創建,
  
  String是程序中最主要創建的對象,因為String是不變的,假如String長度被修改 將導致String對象再次創建,所以對性能有所注重的一般人就是盡量回避使用String, 但是這幾乎是不可能的。
  
  接口參數設計
  
  舉例 MailBot:
  MailBot郵件系統的有一個Header數據,它是character buffer,需要對這個character buffer 進行分析比較,那麼你要做一個類Matcher,在這個類中你將Header數據讀入然後配比,一個不好的做法是:
  
  public class BadRegEXPMatcher {
  public BadRegExpMatcher(String regExp);
  
    /** Attempts to match the specified regular expression against the input   text, returning the matched text if possible or null if not
    */
    public String match(String inputText);
  
  }
  
  這個BadRegExpMatche要求入口參數是String ,那麼假如MailBot要調用他,必須自己做一個 character buffer到String的轉換:
  
  BadRegExpMatcher dateMatcher = new BadRegExpMatcher(...);
  
  while (...) { ...
  
  //產生新的String
  String headerLine = new String(myBuffer, thisHeaderStart, thisHeaderEnd-thisHeaderStart);
  
  String result = dateMatcher.match(headerLine);
  
  if (result == null) { ... }
  
  }
  
  很明顯,這裡這個由於接口不一致導致了多余的對象String headerline的創建,這是不能答應的, 應該將Matcher的接口設計成能夠接納character buffer,當然為通用性,也應該提供String的 接口參數:
  
  class BetterRegExpMatcher {
    public BetterRegExpMatcher(...);
  
    /** 提供多個接口參數的match方法
    Provide matchers for multiple formats of input -- String,
    character array,   and subset of character array. Return
    -1 if no match was made; return offset of match start if
    a match was made. */
   
    public int match(String inputText);
    public int match(char[] inputText);
    public int match(char[] inputText, int offset, int length);
  
    /** Get the next match against the input text, if any */
    public int getNextMatch();
  
    public int getMatchLength();
  
    public String getMatchText();
  }
  
  很明顯BetterRegExpMatcher的運行速度將比前面BadRegExpMatcher運行速度快。
  
  因為在你已經寫好代碼的情況下,你比較難於更改一個類的接口參數,那就應該在寫程序之前多 多考慮你這些接口參數的類型設定,最好有一個通盤的接口類型規定。
  
  減少對象的創建
  
  臨時對象是那些有很短的生命周期,通常服務一些非十分有用的目標,程序員通常使用臨時對象作為 數據混合包傳送或者返回,為避免上述示例哪些轉換接口對象的構造,你應該巧妙的避免創造這些臨時對象,以防止給你的程序留下性能的陰影。
  
  上述示例說明性能問題在於String對象,但是String在對象創建中又是如此的普遍,String是不變的,一旦賦值,就不會變化,不少程序員 認為不變的東西總是會導致壞的性能,其實它並不是這麼簡單,實際上,性能好壞在於你如何使用這個東西。
  
  對於經常需要變化的String,很明顯使用Stringbuffer來代替。
  
  舉例:
  看下面兩種實現:
  
  public class Component {
    ...
    protected Rectangle myBounds;
    public Rectangle getBounds() { return myBounds; }
  
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved