首页 > 解决方案 > 为什么 Arrays.copyOf 这么慢?

问题描述

该功能ArrayList.add()运行速度非常快。我检查了源代码,看到工具是Arrays.copyOf()

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}

但是当我Arrays.copyOf()在我的代码中使用该方法时,它变得非常慢。你可以运行下面的代码来查看它:

public class TestArrayCopy {
  public static void main(String[] args) {
    long t = System.currentTimeMillis();
    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < 100000; i++) {
      list.add(i, i);
    }
    System.out.println(System.currentTimeMillis() - t);

    t = System.currentTimeMillis();
    Integer[] array = new Integer[0];
    for (int i = 0; i < 100000; i++) {
      array = Arrays.copyOf(array, array.length +1);
      array[i] = i;
    }
    System.out.println(System.currentTimeMillis() - t);
  }
}

有任何想法吗?

标签: java

解决方案


如果你问为什么两个循环有不同的运行时间(第二个慢得多),原因是大多数调用list.add(i, i)不需要重新创建支持数组。

只有当后备数组变满时,才会创建更大的数组。并且较大的数组比原始数组大 50%,因此它可以add在它变满之前处理许多后续调用。


推荐阅读