Java中List效率的比較

Java Collections Framework(JCF) 是Java SE中一個基本的類集,幾乎所有的項目都會用到,其中的List 則是JCF中最最常用的一個接口。圍繞List 接口,有很多實現,諸如常用的ArrayList 、LinkedList 、Vector 、Stack ,還有Java5之後引入的CopyOnWriteArrayList ,也有不少List 的開源實現,如Apache commons-collections中的各類List 
  這麼多的List 實現,如何選擇?他們的運行效率具體怎樣?本篇文章將用具體的代碼來檢測其中最最常用的一些List 實現 

主要測試對象: 
  java.util.ArrayList; 
  java.util.LinkedList; 
  java.util.Stack; 
  java.util.Vector; 
  java.util.concurrent.CopyOnWriteArrayList; 
  org.apache.commons.collections.FastArrayList; 
  org.apache.commons.collections.list.TreeList; 
測試用例: 
  1.測試List 
   1.1順序添加 
   1.2隨機插入 
   1.3隨機刪除 
   1.4隨機訪問 
   1.5隨機更新 
   1.5順序迭代 
      1.6for順序迭代 

  2.測試List 在三種情況下的排序效率 
   2.1初始時List 中元素已從小到大有序排列(最優情況) 
   2.2初始時List 中元素已從大到小有序排列(最差情況) 
   2.3初始時List 中元素隨機排列,無序 
  3.測試List 互相轉換的效率 
   3.1轉化爲TreeList 
   3.2轉化爲ArrayList 
   3.3轉化爲LinkedList 
   3.4轉化爲CopyOnWriteArrayList 
   3.5轉化爲Vector 
測試代碼: 
Java代碼  收藏代碼
  1. import static java.lang.System.out;    
  2. import java.util.ArrayList;    
  3. import java.util.Collections;    
  4. import java.util.Iterator;    
  5. import java.util.LinkedList;    
  6. import java.util.List;    
  7. import java.util.Stack;    
  8. import java.util.Vector;    
  9. import java.util.concurrent.CopyOnWriteArrayList;    
  10. import org.apache.commons.collections.FastArrayList;    
  11. import org.apache.commons.collections.list.TreeList;    
  12. import org.apache.commons.lang.StringUtils;    
  13. import org.apache.commons.lang.time.StopWatch;    
  14. @SuppressWarnings("unchecked")    
  15. public class ListPerformance {    
  16.     public static void main(String[] args) {    
  17.         ListPerformance test = new ListPerformance(10 * 10000);    
  18.         out.print(StringUtils.center("Test List Performance: loop=" + test.loop, 80'-'));    
  19.         out.printf("\n ssssssss""""add""insert""remove""get""set",    
  20.                 "iterator","for");    
  21.         test.benchmark(new FastArrayList());    
  22.         test.benchmark(new TreeList());    
  23.         test.benchmark(new ArrayList());    
  24.         test.benchmark(new LinkedList());    
  25.         test.benchmark(new CopyOnWriteArrayList());    
  26.         test.benchmark(new Vector());    
  27.         test.benchmark(new Stack());    
  28.         //2.測試排序    
  29.         out.print("\n\n");    
  30.         out.print(StringUtils.center("Test List sort Performance: loop=" + test.loop, 80'-'));    
  31.         out.printf("\n ssss""""optimize""worst""random");    
  32.         test.benchmarkSort(new FastArrayList());    
  33.         test.benchmarkSort(new TreeList());    
  34.         test.benchmarkSort(new ArrayList());    
  35.         test.benchmarkSort(new LinkedList());    
  36.         //test.benchmarkSort(new CopyOnWriteArrayList());//UnsupportedOperationException    
  37.         test.benchmarkSort(new Vector());    
  38.         test.benchmarkSort(new Stack());    
  39.         //3.測試各種數據結構間轉化    
  40.         out.print("\n\n");    
  41.         out.print(StringUtils.center("Test List convert Performance: loop=" + test.loop, 80'-'));    
  42.         out.printf("\n ssssss""""Tree""Array""Linked""CopyOnWrite",    
  43.                 "Vector");    
  44.         test.benchmarkConvert(new FastArrayList());    
  45.         test.benchmarkConvert(new TreeList());    
  46.         test.benchmarkConvert(new ArrayList());    
  47.         test.benchmarkConvert(new LinkedList());    
  48.         test.benchmarkConvert(new CopyOnWriteArrayList());    
  49.     }    
  50.        
  51.     private int loop = 10000;    
  52.     public ListPerformance(int loop) {    
  53.         this.loop = loop;    
  54.     }    
  55.     public void benchmark(List list) {    
  56.         out.printf("\n s", list.getClass().getSimpleName());    
  57.         int j;    
  58.         StopWatch watch = null;    
  59.         //1.測試順序性能(Add)    
  60.         (watch = new StopWatch()).start();    
  61.         for (int i = 0; i < loop; i++) {    
  62.             list.add(new Integer(i));    
  63.         }    
  64.         watch.stop();    
  65.         out.printf("d", watch.getTime());    
  66.         //2.測試隨機插入性能(Random insert)    
  67.         (watch = new StopWatch()).start();    
  68.         for (int i = 0; i < loop; i++) {    
  69.             j = (int) (Math.random() * loop);    
  70.             list.add(j, new Integer(-j));    
  71.         }    
  72.         watch.stop();    
  73.         out.printf("d", watch.getTime());    
  74.         //3.測試隨機索引刪除(Random remove)    
  75.         (watch = new StopWatch()).start();    
  76.         for (int i = 0; i < loop; i++) {    
  77.             j = (int) (Math.random() * loop);    
  78.             list.remove(j);    
  79.         }    
  80.         watch.stop();    
  81.         out.printf("d", watch.getTime());    
  82.         //4.測試隨機取數性能(Random get)    
  83.         (watch = new StopWatch()).start();    
  84.         for (int i = 0; i < loop; i++) {    
  85.             j = (int) (Math.random() * loop);    
  86.             list.get(j);    
  87.         }    
  88.         watch.stop();    
  89.         out.printf("d", watch.getTime());    
  90.         //5.測試隨機更新性能(Random set)    
  91.         (watch = new StopWatch()).start();    
  92.         for (int i = 0; i < loop; i++) {    
  93.             j = (int) (Math.random() * loop);    
  94.             list.set(j, j);    
  95.         }    
  96.         watch.stop();    
  97.         out.printf("d", watch.getTime());    
  98.         //6.測試迭代性能(Iterator)    
  99.         (watch = new StopWatch()).start();    
  100.         Iterator<Object> iter = list.iterator();    
  101.         while (iter.hasNext()) {    
  102.             iter.next();    
  103.         }    
  104.         watch.stop();    
  105.         out.printf("d", watch.getTime());  
  106.       //7.測試迭代性能(Iterator)    
  107.         (watch = new StopWatch()).start();    
  108.      //   Iterator<Object> iter = list.iterator();    
  109.         for (Object obj : list) {    
  110.             
  111.         }    
  112.         watch.stop();    
  113.         out.printf("d", watch.getTime());  
  114.     }    
  115.     public void benchmarkConvert(List list) {    
  116.         out.printf("\n s", list.getClass().getSimpleName());    
  117.         StopWatch watch = null;    
  118.         //1.轉TreeList    
  119.         (watch = new StopWatch()).start();    
  120.         new TreeList(list);    
  121.         watch.stop();    
  122.         out.printf("d", watch.getTime());    
  123.         //2.轉ArrayList    
  124.         (watch = new StopWatch()).start();    
  125.         new ArrayList(list);    
  126.         watch.stop();    
  127.         out.printf("d", watch.getTime());    
  128.         //3.轉LinkedList    
  129.         (watch = new StopWatch()).start();    
  130.         new LinkedList(list);    
  131.         watch.stop();    
  132.         out.printf("d", watch.getTime());    
  133.         //4.轉CopyOnWriteArrayList    
  134.         (watch = new StopWatch()).start();    
  135.         new CopyOnWriteArrayList(list);    
  136.         watch.stop();    
  137.         out.printf("d", watch.getTime());    
  138.         //5.轉Vector    
  139.         (watch = new StopWatch()).start();    
  140.         new Vector(list);    
  141.         watch.stop();    
  142.         out.printf("d", watch.getTime());    
  143.     }    
  144.     public void benchmarkSort(List list) {    
  145.         out.printf("\n s", list.getClass().getSimpleName());    
  146.         StopWatch watch = null;    
  147.         //1.順序List    
  148.         for (int i = 0; i < loop; i++) {    
  149.             list.add(new Integer(i));    
  150.         }    
  151.         (watch = new StopWatch()).start();    
  152.         Collections.sort(list);    
  153.         watch.stop();    
  154.         out.printf("d", watch.getTime());    
  155.         //2.逆序List    
  156.         for (int i = loop - 1; i > 0; i--) {    
  157.             list.add(new Integer(i));    
  158.         }    
  159.         (watch = new StopWatch()).start();    
  160.         Collections.sort(list);    
  161.         watch.stop();    
  162.         out.printf("d", watch.getTime());    
  163.         //3.隨機順序List    
  164.         for (int i = 0, j = 0; i < loop; i++) {    
  165.             j = (int) (Math.random() * loop);    
  166.             list.add(new Integer(j));    
  167.         }    
  168.         (watch = new StopWatch()).start();    
  169.         Collections.sort(list);    
  170.         watch.stop();    
  171.         out.printf("d", watch.getTime());    
  172.     }    
  173. }   




測試結果: 
-----------------------Test List Performance: loop=100000----------------------- 
                           add    insert    remove       get       set  iterator       for 
       FastArrayList        31     16344     16312        47        62         0         0 
            TreeList       156       391       281       109       110        15         0 
           ArrayList        47     16406     16500        16        47        16         0 
          LinkedList        15    149719    264203    176125    179406         0        31 
CopyOnWriteArrayList     27422    141797    160906        31     65375         0         0 
              Vector        16     26391     24437        31        47        16         0 
               Stack        31     25094     22703        31        16        16         0 
--------------------Test List sort Performance: loop=100000--------------------- 
                      optimize     worst    random 
       FastArrayList        31        78       188 
            TreeList        32        94       343 
           ArrayList        16        94       172 
          LinkedList        16       266       219 
              Vector        15        78       219 
               Stack        15        94       156 
-------------------Test List convert Performance: loop=100000------------------- 
                          Tree     Array    LinkedCopyOnWrite    Vector 
       FastArrayList         0         0         0         0         0 
            TreeList         0         0         0         0         0 
           ArrayList         0         0         0         0         0 
          LinkedList         0         0         0         0         0 
CopyOnWriteArrayList         0         0         0         0         0
 





結論: 
  1.隨機插入、隨機刪除操作中,用TreeList 效率最高; 
  2.在只需要追加、迭代的環境下,LinkedList 效率最高; 
  3.平均效率來講,ArrayList 相對平衡,但如果海量隨機操作,還是會造成性能瓶頸; 
  4.CopyOnWriteArrayList 因爲線程安全的原因,致使性能降低很多,所以慎用; 
  5.Vector 沒有傳說中那麼低的效率; 
  6.讓Stack 來做List 的事可以,不過語義上Stack 不應該做過多的List 的事情; 
  7.在排序中,ArrayList 具有最好的性能,TreeList 平均性能也不錯,LinkedList 的排序效率受元素初始狀態的影響很大。 
  8.各種List 間轉換幾乎沒有時間損耗。 

注:增強性for循環其實是對iterator循環的一種簡單寫法,在編譯時增強性for循環會被編譯爲iterator的for循環寫法。在測試結果中兩者變現出來的性能有一點相差(不正確,有時變現的快,有時變現的慢一點,可能與其他因素有關係),從理論上說,應該基本一樣。 
引用地址:http://ldbjakyo.iteye.com/blog/1142899

http://blog.sina.com.cn 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章