数组、ArrayList、LinkedList查询及遍历性能分析 .

最近研究spring框架时,发现它在存储以查询和遍历居多的数据时采用的数组,而不是现在很多书中推荐的List。并且之前也发现tomcat在实现自己的service和connector时,也是多采用数组的方式。虽然之前也大概了解到list,特别是linkedList和数组在数据查询上确实有差距,但是没有深入的分析过。所以这里就写了个程序测试一下数组、ArrayList、LinkedList在遍历和查询方面的性能。

 

首先代码:

[c-sharp] view plain copy print ?
  1. package test;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.LinkedList;  
  5.   
  6. import org.junit.Before;  
  7. import org.junit.Test;  
  8.   
  9. /** 
  10.  * 数组及List查询和遍历性能比对 
  11.  * @author gaoyusi 
  12.  * @see http://blog.csdn.net/gaoyusi4964238 
  13.  */  
  14. public class TestArrayAndList {  
  15.   
  16.     /* 
  17.      * count:10,100,1000,10000,100000 
  18.      * idx:  6,60,600,6000,60000 
  19.      */  
  20.     private static final int COUNT=10000;  
  21.       
  22.     private static final int IDX=6;  
  23.       
  24.     private String[] array;  
  25.       
  26.     private ArrayList<String> arrayList;  
  27.       
  28.     private LinkedList<String> linkList;  
  29.       
  30.     @Before  
  31.     public void init(){  
  32.         array=new String[COUNT];  
  33.         arrayList=new ArrayList<String>(COUNT);  
  34.         linkList=new LinkedList<String>();  
  35.         for(int i=0;i<COUNT;i++){  
  36.             array[i]="test";  
  37.             arrayList.add("test");  
  38.             linkList.add("test");  
  39.         }  
  40.     }  
  41.       
  42.     @Test  
  43.     public void  testTraverse(){  
  44.         System.out.println("Traverse Time:");  
  45.         long startTime=System.nanoTime();  
  46.         array();  
  47.         System.out.println(">>>array:"+(System.nanoTime()-startTime));  
  48.           
  49.         startTime=System.nanoTime();  
  50.         arrayList();  
  51.         System.out.println(">>>aList:"+(System.nanoTime()-startTime));  
  52.           
  53.         startTime=System.nanoTime();  
  54.         linkList();  
  55.         System.out.println(">>>lList:"+(System.nanoTime()-startTime));  
  56.     }  
  57.       
  58.     @Test  
  59.     public void  testQuery(){  
  60.         System.out.println("Query Time:");  
  61.         long startTime=System.nanoTime();  
  62.         String test=array[IDX];  
  63.         System.out.println(">>>array:"+(System.nanoTime()-startTime));  
  64.           
  65.         startTime=System.nanoTime();  
  66.         arrayList.get(IDX);  
  67.         System.out.println(">>>aList:"+(System.nanoTime()-startTime));  
  68.           
  69.         startTime=System.nanoTime();  
  70.         linkList.get(IDX);  
  71.         System.out.println(">>>lList:"+(System.nanoTime()-startTime));  
  72.     }  
  73.       
  74.     public void array(){  
  75.         int i=0;  
  76.         for(String a:array){  
  77.             i++;  
  78.         }  
  79.     }  
  80.       
  81.     public void arrayList(){  
  82.         int i=0;  
  83.         for(String a:arrayList){  
  84.             i++;  
  85.         }  
  86.     }  
  87.       
  88.     public void linkList(){  
  89.         int i=0;  
  90.         for(String a:linkList){  
  91.             i++;  
  92.         }  
  93.     }  
  94. }  

 

测试结果如下:

count:10,idx:  6

 

count:100,idx:  60

count:1000,idx:  600

 

count:10000,idx:  6000

 

count:100000,idx:  60000

 

 

从以上测试结果可得到以下结论:

1.array在容量在比较小时,遍历的性能优势不够明显,但是随着容量的不断增大,其遍历性能优势会不断显现。

2.array的查询性能要优于list,而且随着array容量增加,这种优势也更加突出。

3.linkedList在遍历上性能不够稳定。

4.在list容量较大情况下,ArrayList查询数据要远优于LinkedList

 

分析:

对于结论1和2,在容量比较小的情况下,有点困惑,估计是array和list对于资源消耗比较小。在容量较大情况下,list性能较差原因主要是需要转型,对于ArrayList,其数据其实是存放于一个Obejct[]中的,那么他在查询和遍历返回时需要强制转型,这样隐形增加其开销,这个可以从其源代码中看出:

 

[c-sharp] view plain copy print ?
  1. public E get(int index) {  
  2. RangeCheck(index);  
  3.   
  4. return (E) elementData[index];  
  5.    }  

而对于LinkedList,虽然不需要强制转型,但是根据java中泛型的工作原理,jvm还是对相应的数据进行了隐性的转型。

虽然这中转型开销不是特别庞大,但是在大数据量的遍历过程中,其累加起来的消耗还是相当大的。

 

对于结论3和4,主要原因是因为LinkedList是利用双向循环链表实现的,参见一下linkedList的构造函数:

[c-sharp] view plain copy print ?
  1. public LinkedList() {  
  2.        header.next = header.previous = header;  
  3.    }  

所以其在查询过程中,不能像array或arrayList那样直接定位到对应的数据节点,而是必须遍历到具体的位置来实现,对于大容量数据来说,这个过程会相当消耗时间(不过这也造就了其在频繁修改和增加数据时的高性能)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值