为什么克隆()是复制阵列的最佳方式?

我很遗憾,但我不知道:

您应该使用克隆来复制阵列,因为这通常是
最快的方法

正如Josh Bloch在本博客中所说:http://www.artima.com/intv/bloch13.html

我总是使用System.arraycopy(…)
这两种方法都是本地的,所以如果不深入了解库的来源,我可能无法理解为什么会这样

我的问题很简单:
为什么这是最快的方式?
System.arraycopy与有什么区别?
这里解释了这一区别,但它并没有回答为什么Josh Bloch认为clone()是最快的方法的问题

我想谈谈为什么clone()是比System.arraycopy(…)或其他方法复制阵列最快的方法:

1。clone()在将源数组复制到目标数组之前,不必进行类型检查,如此处所述。它只是简单地分配新的内存空间并将对象分配给它。另一方面,System.arraycopy(..)检查类型,然后复制数组

2.clone()也会中断优化,以消除冗余调零。正如您所知,Java中每个分配的数组都必须用0s或各自的默认值初始化。但是,如果JIT看到数组在创建后立即被填充,则可以避免将该数组归零。与使用现有的0s或相应的默认值更改副本值相比,这无疑会更快。使用System.arraycopy(..)时,会花费大量时间清除和复制初始化的数组。为此,我执行了一些基准测试

@BenchmarkMode(模式吞吐量)
@叉子(1)
@状态(Scope.Thread)
@预热(迭代次数=10,时间=1,批量大小=1000)
@测量(迭代次数=10,时间=1,批量大小=1000)
公共类基准测试{
@参数({“1000”、“100”、“10”、“5”、“1”})
私有整数大小;
私人int[]原件;
@设置
公共作废设置(){
原始=新整数[大小];
对于(int i=0;i<size;i++){
原[i]=i;
}
}
@基准
public int[]SystemArrayCopy(){
最终整数长度=大小;
int[]目的地=新的int[长度];
System.arraycopy(原始,0,目的地,0,长度);
返回目的地;
}
@基准
公共int[]arrayClone(){
返回original.clone();
}
}

输出:

基准(大小)模式Cnt分数错误单位
ArrayCopy.SystemArrayCopy 1 thrpt 10 26324.251±1532.265 ops/s
ArrayCopy.SystemArrayCopy 5 thrpt 10 26435.562±2537.114 ops/s
ArrayCopy.SystemArrayCopy 10 thrpt 10 27262.200±2145.334 ops/s
ArrayCopy.SystemArrayCopy 100 thrpt 10 10524.117±474.325 ops/s
ArrayCopy.SystemArrayCopy 1000 thrpt 10 984.213±121.934 ops/s
ArrayCopy.ArrayCyclone 1 thrpt 10 55832.672±4521.112 ops/s
ArrayCopy.ArrayCyclone 5 thrpt 10 48174.496±2728.928 ops/s
ArrayCopy.ArrayCyclone 10 thrpt 10 46267.482±4641.747 ops/s
ArrayCopy.ArrayCyclone 100 thrpt 10 19837.480±364.156 ops/s
ArrayCopy.ArrayCyclone 1000 thrpt 10 1841.145±110.322 ops/s

根据我得到的输出,cloneSystem.arraycopy(…)

3。此外,使用手动复制方法,如clone()会导致更快的输出,因为它不必进行任何VM调用(与System.arraycopy()不同)

发表评论