1. 程式人生 > >後臺程式效能優化

後臺程式效能優化

一. 優化原則:

1、減少資料庫訪問次數

(1) 使用資料快取的存取方式

(2) 使用批量處理的方式

2、減少SQL語句的執行時間

(1) 使用佔位符的訪問方式

(2) 優化SQL的執行計劃(比如使用資料庫索引或者調整SQL)


3、 減少程式執行的時間

(1) 使用非同步呼叫代替同步呼叫

(2) 使用本地API方式代替遠端呼叫(比如WebSerivce)

(3) 減少同步塊或者同步方法的使用

(4) 減少IO讀寫

4、減少請求壓力

(1) 使用應用叢集部署方式分擔掉伺服器的壓力

(2) 將靜態檔案和動態檔案分離部署,減少J2EE容器的壓力

二. 高效Java:

1、儘量避免不必要的方法呼叫

原則:在Java中,一切都是物件,如果有方法(Method)呼叫,處理器先要檢查該方法是屬於哪個物件,該物件是否有效,物件屬於什麼型別,然後選擇合適的方法並呼叫。儘可能在外層確定是否一定要執行該方法。

優化前:

  1. public void CallMethod(int i ){    
  2.  if( i ==0 ){    
  3.   return;    
  4.  }    
  5.  ... // 其他處理    
  6. }    
  7. int i = 0;    
  8. ...    
  9. CallMethod(i);  

優化後:

  1. int i = 0;    
  2. ...    
  3. if( i ==0 ){    
  4.  CallMethod(i);    
  5. }    

2、儘量避免不必要的物件建立

原則:當一個物件是用new進行初始化時,其建構函式鏈的所有建構函式都被呼叫到,所以new操作符是很消耗系統資源的,new一個物件耗時往往是區域性變數賦值耗時的上千倍。同時,當生成物件後,系統還要花時間進行垃圾回收和處理。儘量少用new來初始化一個類的例項, 當new建立物件不可避免時,注意避免多次的使用new初始化一個物件,儘量在使用時再建立該物件。

優化前:

  1. NewObject object = new NewObject();  
  2. int value;  
  3. if(i>0 )  
  4. {  
  5.  value =object.getValue();  
  6. }  

優化後:

  1. int value;  
  2. if(i>0 )  
  3. {  
  4.  NewObject object = new NewObject();  
  5.  Value =object.getValue();  
  6. }  

3、儘量減少對變數的重複計算體

原則:迴圈是比較重複執行的地方,如果迴圈次數很大,迴圈體內不好的程式碼對效率的影響就會被放大而變的突出。當有較大的迴圈時,應該檢查迴圈內是否有效率不高的地方,尋找更優的方案加以改進。

優化前:

  1. Vector vect = new Vector(1000);  
  2. ...  
  3. forint i=0; i<vect.size(); i++){  
  4.  ...  
  5. }  

優化後:

  1. int size = vect.size();  
  2. forint i=0; i<size; i++){  
  3.  ...  
  4. }  

4、生成物件時,分配合理的空間和大小

原則:Java中的很多類都有它的預設的空間分配大小,對於一些有大小的物件的初始化,應該預計物件的大小,然後使用進行初始化。

StringBuilder builder = new StringBuilder(100);

5、使用StringBuilder代替String

原則:String是用來儲存字串常量的,如果要執行“+”的操作,系統會生成一些臨時的物件,並對這些物件進行管理,造成不必要的開銷。如果字串有連線的操作,替代的做法是用StringBuilder的append方法,StringBuffer是有同步機制的,效率上沒有StringBuilder快。

6、控制查詢返回的結果條數

原則:當查詢返回的資料量過大時,通過擷取前面100條的資料返回,不然將嚴重影響系統的響應時間。

7、多執行緒不能使用HashMap

原則:HashMap沒有同步機制,用於多執行緒的頻繁讀寫會產生執行緒死鎖的情況。推薦使用ConcurrentHashMap來代替HashMap,在初時化時儘量傳入大小容量。

8、不要在迴圈中使用try…catch

原則:在迴圈中使用try…catch的話會造成多次異常判斷邏輯,儘量做到一個方法最多隻有一個try…catch塊。

9、使用高效的HashMap的遍歷

低效率的遍歷方式:

  1. Map map = new HashMap();   
  2. Iterator iter = map.keySet().iterator();   
  3. while (iter.hasNext()) {   
  4.   Object key = iter.next();   
  5.   Object val = map.get(key);   
  6. }  

高效率的遍歷方式:

  1. Map map = new HashMap();   
  2. Iterator iter = map.entrySet().iterator();   
  3. while (iter.hasNext()) {   
  4.   Map.Entry entry = (Map.Entry) iter.next();   
  5.   Object key = entry.getKey();   
  6.   Object val = entry.getValue();   
  7. }  

第一種對於keySet其實是遍歷了2次,一次是轉為iterator,一次就從hashmap中取出key所對於的value。

第二種entryset只是遍歷了第一次,他把key和value都放到了entry中,所以會比第一種快。

三. 高效SQL

1、儘量不用萬用字元“%”或者“_”作為查詢字串的第一個字元

當萬用字元“%”或者“_”作為查詢字串的第一個字元時,索引不會被使用。比如用 T 表中 Column1  LIKE  ‘%5400%’  這個條件會產生全表掃描,如果改成  Column1  ‘X5400%’  OR Column1 LIKE ‘B5400%’  則會利用 Column1 的索引進行兩個範圍的查詢,效能肯定大大提高。

2、儘量EXISTS替換IN 操作符(主要考慮索引是否能用上的問題)

基本上所有的 IN 操作符都可以用 EXISTS 代替,在選擇 IN 或 EXIST 操作時,要根據主子表資料量大小來具體考慮。

3、用 UNION ALL 代替 UNION

UNION 是最常用的集操作,使多個記錄集聯結成為單個集,對返回的資料行有唯一性要求, 所以 oracle 就需要進行 SORT UNIQUE 操作(與使用 distinct 時操作類似),如果結果集又 比較大,則操作會比較慢;

UNION  ALL 操作不排除重複記錄行,所以會快很多,如果資料本身重複行存在可能性較

小時,用 union all 會比用 union 效率高很多!

4、SELECT子句中避免使用“*”號

ORACLE在解析的過程中, 會將'*' 依次轉換成所有的列名, 這個工作是通過查詢資料字典完成的, 這意味著將耗費更多的時間。

5、儘量用 NOT EXISTS 或者外連線替代 NOT IN 操作符

因為 NOT IN 不能應用表的索引。

6、儘量不用“<>”或者“!=”操作符

不等於操作符是永遠不會用到索引的,因此對它的處理只會產生全表掃描。比如:a<>0

改為  a>0 or a<0

參考資料: http://chenjc-it.iteye.com/blog/1565143