1. 程式人生 > >三種迴圈的效能比較

三種迴圈的效能比較

下面是一段測試程式碼:

List<Integer> integers = new ArrayList<Integer>();
    for (int i = 0; i < 10000000; i++) {
        integers.add(i);
    }
    long l1 = System.currentTimeMillis();
    for (int i = 0; i < integers.size(); i++) {
        integers.get(i);
    }
    long l2 = System.currentTimeMillis();
    System.out.println(l2 - l1);
    Iterator<Integer> iterator = integers.iterator();
    while (iterator.hasNext()) {
        iterator.next();
    }
    long l3 = System.currentTimeMillis();
    System.out.println(l3-l2);
    for (Integer i : integers) {

    }
    System.out.println(System.currentTimeMillis()-l3);
}
  • 第一種迴圈是最經典的 for 迴圈
  • 第二種迴圈是 Iterator 迴圈
  • 第三種迴圈是 for-each 迴圈

下面是三種迴圈所需要的時間:
這裡寫圖片描述

很顯然第一種迴圈的效率最高,第二種次之,第三種最差。隱約記得,在剛工作的時候帶我的師傅說最好用 for-each 迴圈,程式碼簡潔,效率還高,我一直以為也是這樣。

今天,我看了 RandomAccess 介面的文件說明,文件中明確說明了實現了 RandomAccess 介面的類使用經典的 for 迴圈要比使用 Iterator 迴圈更快(ArrayLis 實現了 RandomAccess 介面)。動手試了下果然如此,for-each 迴圈的底層也是使用了 Iterator ,只是對 Iterator 進行了包裝。

下面是另一段程式碼,除了第一行和迴圈的大小不同外其餘的地方都相同。上一個例子中 List 的實現是 ArrayList ,下面的例子中 List 的實現是 LinkedList 。

public static void main(String[] args) {
    List<Integer> integers = new LinkedList<Integer>();
    for (int i = 0; i < 100000; i++) {
        integers.add(i);
    }
    long l1 = System.currentTimeMillis();
    for (int i = 0; i < integers.size(); i++) {
        integers.get(i);
    }
    long l2 = System.currentTimeMillis();
    System.out.println(l2 - l1);
    Iterator<Integer> iterator = integers.iterator();
    while (iterator.hasNext()) {
        iterator.next();
    }
    long l3 = System.currentTimeMillis();
    System.out.println(l3-l2);
    for (Integer i : integers) {

    }
    System.out.println(System.currentTimeMillis()-l3);
}

下面是三種迴圈所需要的時間:

這裡寫圖片描述
在這種情況下經典的 for 迴圈要比另外兩種迴圈慢的多。文件中說了,實現了 RandomAccess 介面的類使用經典的迴圈要比 Iterator 迴圈要快。ArrayList 實現了 RandomAccess 介面,但 LinkedList 並沒有實現 RandomAccess 介面。由於 ArrayList 的底層實現是陣列,通過下標常量時間訪問,訪問快, LinkedList 底層實現是連結串列,訪問時間的平均長度與 LinkedList 的容量成正比,是線性訪問時間,所以慢。