java - 为什么 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);
}
}
有任何想法吗?
解决方案
如果你问为什么两个循环有不同的运行时间(第二个慢得多),原因是大多数调用list.add(i, i)
不需要重新创建支持数组。
只有当后备数组变满时,才会创建更大的数组。并且较大的数组比原始数组大 50%,因此它可以add
在它变满之前处理许多后续调用。
推荐阅读
- r - 根据 R 中另一列的条件,用相同的值填充整个新列
- javascript - React Typescript ContextAPI 正确使用接口的方法
- etl - 有多少 Talend 功能在 SQL-Query 中翻译,多少在 Java 中?
- html - 在具有两级行跨度的表上定位粘性
- sql - 这是通过grafana使用它的正确方法吗?
- python - Pandas groupby:一次调用 ffill() + tail(1)?
- java - String.getBytes 是否被安全使用?
- reactjs - 在修改组件的文件中调用方法
- amazon-web-services - 使用启动模板进行计划扩展尝试减少机器数量时,它会卡住待处理的操作
- html - 无法将图像放入网格卡内