Java中迭代列表中數據時幾種循環寫法的效率比較

Java中常常會用到迭代列表數據的狀況,本文針對幾種經常使用的寫法進行效率比較。雖然網上已經有了相似的文章,可是對他們的結論並不認同。java

常見的實現方法:

1.for循環:數組

[java]  view plain copy print ?函數

  1. for(int i = 0; i < list.size(); i++)  
  2. for(int i = 0, size = list.size(); i < size; i++)  

 

通常人都會認爲第二種寫法效率高。測試

 

 

2.foreach:spa

 

 

[java]  view plain copy print ?.net

  1. for(Object obj : list)  


這是一種簡潔的寫法,只能對列表進行讀取,沒法修改。對象

 

3.while:blog

[java]  view plain copy print ?開發

  1. int size = list.size();  
  2. while(size-- > 0)  


4.迭代:get

[java]  view plain copy print ?

  1. Object iter = list.iterator();  
  2. while(iter.hasNext()) {  
  3.   iter.next();  
  4. }  

 

測試代碼:

 針對以上幾種方法編寫的測試代碼。

[java]  view plain copy print ?

  1. public static void main(String[] args) {  
  2.       List<Integer> list = new ArrayList<Integer>();  
  3.   
  4.       int runTime = 1000;//執行次數  
  5.       for (int i = 0; i < 1000 * 1000; i++) {  
  6.           list.add(i);  
  7.       }  
  8.       int size = list.size();  
  9.       long currTime = System.currentTimeMillis();//開始分析前的系統時間  
  10.       //基本的for              
  11.       for(int j = 0; j < runTime; j++) {  
  12.           for (int i = 0; i < size; i++) {  
  13.               list.get(i);  
  14.           }  
  15.       }  
  16.       long time1 = System.currentTimeMillis();  
  17.   
  18.       //foreach  
  19.       for(int j = 0; j < runTime; j++) {  
  20.           for (Integer integer : list) {  
  21.           }  
  22.       }  
  23.       long time2 = System.currentTimeMillis();  
  24.   
  25.       for(int j = 0; j < runTime; j++) {  
  26.           //while  
  27.           int i = 0 ;  
  28.           while(i < size){  
  29.               list.get(i++);  
  30.           }  
  31.       }  
  32.       long time3 = System.currentTimeMillis();  
  33.   
  34.       for(int j = 0; j < runTime; j++) {//普通for循環  
  35.           for (int i = 0; i < list.size(); i++) {  
  36.               list.get(i);  
  37.           }  
  38.       }  
  39.       long time4 = System.currentTimeMillis();  
  40.   
  41.       for(int j = 0; j < runTime; j++) {//迭代  
  42.           Iterator<Integer> iter = list.iterator();  
  43.           while(iter.hasNext()) {  
  44.               iter.next();  
  45.           }  
  46.       }  
  47.       long time5 = System.currentTimeMillis();  
  48.   
  49.       long time = time1 - currTime ;  
  50.       System.out.print("use for:" + time);  
  51.       time = time2 - time1;  
  52.       System.out.print("\tuse foreach:" + time);  
  53.       time = time3 - time2;  
  54.       System.out.print("\tuse while:" + time);  
  55.       time = time4 - time3;  
  56.       System.out.print("\tuse for2:" + time);  
  57.       time = time5 - time4;  
  58.       System.out.print("\tuse iterator:" + time);  
  59.       System.out.println();  
  60.   }  

 

輸出結果(JDK1.6):

 

1.

use for:8695        use foreach:17091        use while:6867        use for2:7741        use iterator:14144

2.

use for:8432        use foreach:18126        use while:6905        use for2:7893        use iterator:13976

3.

use for:8584        use foreach:17177        use while:6875        use for2:7707        use iterator:14345
 

結論:

1.針對列表的 foreach的效率是最低:

耗時是普通for循環的2倍以上。我的理解它的實現應該和iterator類似。

2. list.size()的開銷很小:

list.size()次數多少對效率基本沒有影響。查看ArrayList的實現就會發現,size()方法的只是返回了對象內的長度屬性,並無其它計算,因此只存在函數調用的開銷。

對數組的測試:

將代碼中的列表list換作數組再進行測試(iterator不適用),發現耗時基本爲0。說明:

 

3. 列表的get()方法開銷很多

應該主要是檢測數據合法性時產生的。

將執行次數增長100萬倍,這時能夠看出結果基本相等,並無明顯的差別。說明:

4. 數組length也沒有開銷

可見數組長度並非每次執行的時候都要計算的。聯想一下Java建立數組的時候要求必須指定數組的長度,編譯處理的時候顯然沒有把這個值拋棄掉。

 

網上有一篇相似的文章,它竟然得出了一個foreach執行效率最高的結論。看一下它的測試代碼就會發現一個要命的問題,它竟然在執行每次循環的時候調用了System.out.print()方法將數組內容輸出,難道他不知道這個操做耗時很是大嗎,這樣計算出的結果有什麼用處呢。

後續有不少開發填坑的文章發佈,若是對你有幫助,請支持和加關注一下

http://e22a.com/h.05ApkG?cv=AAKHZXVo&sm=339944

https://shop119727980.taobao.com/?spm=0.0.0.0 

相關文章
相關標籤/搜索