我很遗憾,但我不知道:
您应该使用克隆来复制阵列,因为这通常是
最快的方法
正如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
根据我得到的输出,clone
从System.arraycopy(…)
3。此外,使用手动复制方法,如clone()
会导致更快的输出,因为它不必进行任何VM调用(与System.arraycopy()
不同)