此测试
for (;;) {
int[] a = new int[10];
System.gc();
long t0 = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
// int[] b = a.clone();
int[] b = Arrays.copyOf(a, a.length);
}
System.out.println(System.currentTimeMillis() - t0);
}
表示Arrays.copyOf约为50ms,克隆表示约160ms。克隆是一种特殊的本地复制方法,为什么这么慢?
我在HotSpot Client JVM 1.7.0_11-b21上运行测试。请注意,当数组大小增加时,clone和copyOf之间的差异将消失。
答案 0 :(得分:5)
我在我的系统上运行了你的代码:它们之间几乎没有区别。两个时钟都在大约30毫秒。我的测试是在OpenJDK 7上进行的。
要确认我还通过Caliper运行它,并使用更大的数组来强调实际的复制性能:
public class Performance extends SimpleBenchmark {
final int[] source = new int[1000];
public int timeClone(int reps) {
int sum = 0;
for (int i = reps; i > 0; i--)
sum += source.clone().length;
return sum;
}
public int timeCopyOf(int reps) {
int sum = 0;
for (int i = reps; i > 0; i--)
sum += Arrays.copyOf(source,source.length).length;
return sum;
}
public static void main(String... args) {
Runner.main(Performance.class, args);
}
}
结果:
0% Scenario{vm=java, trial=0, benchmark=Clone} 2141.70 ns; σ=5416.80 ns @ 10 trials
50% Scenario{vm=java, trial=0, benchmark=CopyOf} 2168.38 ns; σ=1545.85 ns @ 10 trials
benchmark us linear runtime
Clone 2.14 =============================
CopyOf 2.17 ==============================
vm: java
trial: 0
每个请求,这里的数组大小为10:
0% Scenario{vm=java, trial=0, benchmark=Clone} 30.07 ns; σ=2.12 ns @ 10 trials
50% Scenario{vm=java, trial=0, benchmark=CopyOf} 29.34 ns; σ=161.38 ns @ 10 trials
benchmark ns linear runtime
Clone 30.1 ==============================
CopyOf 29.3 =============================
答案 1 :(得分:0)
我找到了一篇很好的文章,解释了为什么克隆在这里很慢http://www.javaspecialists.eu/archive/Issue124.html。简而言之,这是因为int []。clone只使用Object.clone,这个方法在复制数组之前进行两次检查:
1.检查实例是否为普通对象或数组。
2.检查数组是基元还是对象。
我将这些检查添加到Arrrays.copyOf测试
for (int i = 0; i < 1000000; i++) {
Class cls = a.getClass();
if (cls.isArray() && !cls.getComponentType().isAssignableFrom(Object.class)) {
int[] b = Arrays.copyOf(a, a.length);
}
}
并且测试显示clone和Arrays.copyOf之间没有差异。如果它是一个专门的数组版本克隆会很快。