三种循环的性能比较

下面是一段测试代码:

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 循环

下面是三种循环所需要的时间:
三种循环的性能比较_第1张图片

很显然第一种循环的效率最高,第二种次之,第三种最差。隐约记得,在刚工作的时候带我的师傅说最好用 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);
}

下面是三种循环所需要的时间:

三种循环的性能比较_第2张图片
在这种情况下经典的 for 循环要比另外两种循环慢的多。文档中说了,实现了 RandomAccess 接口的类使用经典的循环要比 Iterator 循环要快。ArrayList 实现了 RandomAccess 接口,但 LinkedList 并没有实现 RandomAccess 接口。由于 ArrayList 的底层实现是数组,通过下标常量时间访问,访问快, LinkedList 底层实现是链表,访问时间的平均长度与 LinkedList 的容量成正比,是线性访问时间,所以慢。

你可能感兴趣的:(三种循环的性能比较)