Java中常常會用到迭代列表數據的狀況,本文針對幾種經常使用的寫法進行效率比較。雖然網上已經有了相似的文章,可是對他們的結論並不認同。java
常見的實現方法:
1.for循環:數組
[java] view plain copy print ?函數
- for(int i = 0; i < list.size(); i++)
- for(int i = 0, size = list.size(); i < size; i++)
通常人都會認爲第二種寫法效率高。測試
2.foreach:spa
[java] view plain copy print ?.net
- for(Object obj : list)
這是一種簡潔的寫法,只能對列表進行讀取,沒法修改。對象
3.while:blog
[java] view plain copy print ?開發
- int size = list.size();
- while(size-- > 0)
4.迭代:get
[java] view plain copy print ?
- Object iter = list.iterator();
- while(iter.hasNext()) {
- iter.next();
- }
測試代碼:
針對以上幾種方法編寫的測試代碼。
[java] view plain copy print ?
- public static void main(String[] args) {
- List<Integer> list = new ArrayList<Integer>();
-
- int runTime = 1000;//執行次數
- for (int i = 0; i < 1000 * 1000; i++) {
- list.add(i);
- }
- int size = list.size();
- long currTime = System.currentTimeMillis();//開始分析前的系統時間
- //基本的for
- for(int j = 0; j < runTime; j++) {
- for (int i = 0; i < size; i++) {
- list.get(i);
- }
- }
- long time1 = System.currentTimeMillis();
-
- //foreach
- for(int j = 0; j < runTime; j++) {
- for (Integer integer : list) {
- }
- }
- long time2 = System.currentTimeMillis();
-
- for(int j = 0; j < runTime; j++) {
- //while
- int i = 0 ;
- while(i < size){
- list.get(i++);
- }
- }
- long time3 = System.currentTimeMillis();
-
- for(int j = 0; j < runTime; j++) {//普通for循環
- for (int i = 0; i < list.size(); i++) {
- list.get(i);
- }
- }
- long time4 = System.currentTimeMillis();
-
- for(int j = 0; j < runTime; j++) {//迭代
- Iterator<Integer> iter = list.iterator();
- while(iter.hasNext()) {
- iter.next();
- }
- }
- long time5 = System.currentTimeMillis();
-
- long time = time1 - currTime ;
- System.out.print("use for:" + time);
- time = time2 - time1;
- System.out.print("\tuse foreach:" + time);
- time = time3 - time2;
- System.out.print("\tuse while:" + time);
- time = time4 - time3;
- System.out.print("\tuse for2:" + time);
- time = time5 - time4;
- System.out.print("\tuse iterator:" + time);
- System.out.println();
- }
輸出結果(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