三種迴圈的效能比較
阿新 • • 發佈:2019-01-05
下面是一段測試程式碼:
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 的容量成正比,是線性訪問時間,所以慢。