我正盯着一个配置文件,其中一个CPU热点是一个包含克隆最终静态int []的函数。你可能会问,'为什么?'调用者使用结果作为散列过程的起点。
换句话说,代码需要(逻辑上):
在我放弃或开始使用微基准测试之前,我发布了这个问题,以防任何人对使用clone()与Arrays.copyOf以及新的和arraycopy的内幕有什么特别的了解。
答案 0 :(得分:5)
Arrays.copyOf
充分利用了记忆,就像引擎盖下的说明一样。此外,索引越界检查越少。如果您逐个指定值,则每次都会进行“绑定”检查。
我没有针对每个建议的选项进行基准测试,但我确信Arrays.copyOf()
会比new int[] + for(...)
更快。
另一方面,我不确定Arrays.copyOf()
是否比int[] myCopy = myOrig.clone()
更有效,因为克隆发生在基本类型数组上。编译器很有可能生成优化的字节码。只有测试才能提供明确的答案。
答案 1 :(得分:3)
Arrays.copyOf
使用System.arraycopy
但首先添加了一些边界检查
public static int[] copyOf(int[] original,
int newLength)
{
if (0 < = newLength) {
return copyOfRange(original, 0, newLength);
}
throw new NegativeArraySizeException();
}
public static int[] copyOfRange(int[] original,
int start,
int end)
{
if (start < = end) {
if (original.length >= start && 0 < = start) {
int length = end - start;
int copyLength = Math.min(length, original.length - start);
int[] copy = new int[length];
System.arraycopy(original, start, copy, 0, copyLength);
return copy;
}
throw new ArrayIndexOutOfBoundsException();
}
throw new IllegalArgumentException();
}
我是从http://www.docjar.com/docs/api/java/util/Arrays.html得到的,所以使用它可能略微比Arrays.copyOf
int[] newone = new int[orig.length];
System.arraycopy(orig, 0, newone , 0, orig.length);
但实际上最好保留数组并在完成后重复使用它们
答案 2 :(得分:0)
如果代码属于您,请执行以下操作:
public final class ReadOnlyIntArray {
private final int[] _contents;
public ReadOnlyIntArray(int[] data) {
_contents = (int[]) data.clone();
}
public int get(int index) {
return _contents[index];
}
}
将final static
内容保留在其中一个内容中,并返回此对象而不是int[]
。如果他们做任何破坏性的事情,强迫消费者克隆。
我经常觉得这个构造应该是java.lang中的核心构造之一,它允许返回Class[]
,Method[]
等的代码不必每次都克隆
答案 3 :(得分:0)
在基本类型数组上使用clone()
比使用Java 1.6 / 1.7 x86客户端虚拟机的new []
和System.arraycopy
组合慢约50%,但速度与x64服务器VM。
对于1000个或更少元素的数组大小,复制不是操作中最昂贵的部分,而是数组本身的创建(即创建2048个元素的字节数组需要3倍于将2048个元素复制到System.arraycopy
)。如果你回收临时阵列,你可以获得一些改进。