Java 效率更高的是:System.arraycopy还是Arrays.copyOf?
在Java 效率更高的是:System.arraycopy还是Arrays.copyOf?,java,arrays,performance,Java,Arrays,Performance,在ArrayList中的toArray方法中,Bloch使用System.arraycopy和Arrays.copyOf来复制数组 public <T> T[] toArray(T[] a) { if (a.length < size) // Make a new array of a's runtime type, but my contents: return (T[]) Arrays.copyOf(elementData, size
ArrayList
中的toArray
方法中,Bloch使用System.arraycopy
和Arrays.copyOf
来复制数组
public <T> T[] toArray(T[] a) {
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
public T[]toArray(T[]a){
如果(a.长度<尺寸)
//创建a的运行时类型的新数组,但我的内容:
return(T[])array.copyOf(elementData,size,a.getClass());
System.arraycopy(elementData,0,a,0,size);
如果(a.长度>尺寸)
a[size]=null;
返回a;
}
如何比较这两种复制方法以及何时使用哪种方法?System.arrayCopy速度更快。它之所以在系统中,是因为它使用Java land之外的直接内存拷贝。尽可能使用它。是本机实现的,因此比任何Java代码都要快。我建议您使用它。区别在于
数组。copyOf
不仅复制元素,还创建新数组<代码>系统。阵列复制复制到现有阵列中
以下是数组.copyOf
的源代码,您可以看到它在内部使用System.arraycopy
填充新数组:
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
<代码>公共静态t[]复制(U[]原始、int NethLoad、类< P>而<代码>系统。ARRAYPrime<代码>是本地实现的,因此可以比java循环快一点,但它并不总是像您预期的那么快。
Object[] foo = new Object[]{...};
String[] bar = new String[foo.length];
System.arraycopy(foo, 0, bar, 0, bar.length);
在这种情况下,foo
和bar
数组具有不同的基本类型,因此arraycopy
的实现必须检查复制的每个引用的类型,以确保它实际上是对字符串实例的引用。这比数组内容的简单C样式memcopy
要慢得多美国
另一点是Arrays.copyOf
在引擎盖下使用System.arraycopy
。因此System.arraycopy
表面上的速度不应该比Arrays.copyOf
慢2。但是您可以看到(从引用的代码中)在某些情况下,array.copyOf
将使用反射来创建新的数组。因此性能比较并不简单
这种分析有几个缺陷
数组中。copyOf
;请参阅。这种方法是“固有的”在当前一代Java实现中,这意味着JIT编译器将忽略Java源代码中的内容O(1)
(即独立于数组大小)且相对较小。因此,我的建议是使用使代码更易于阅读的版本,如果分析告诉您这很重要,只需担心哪一个更快
1-它可能更快,但JIT编译器也可能在优化手动编码循环方面做得很好,没有什么区别。如果您想要一个数组的精确副本(比如,如果您想要做一个防御性副本),复制数组的最有效方法可能是使用数组对象的
克隆()
方法:
class C {
private int[] arr;
public C(int[] values){
this.arr = values.clone();
}
}
我没有费心去测试它的性能,但它很有可能非常快,因为它都是本机的(在调用中分配和复制),而克隆是一种特殊的复制对象的方式(对于其他目的来说,它通常是有害的),并且可能会采取一些“捷径”
就我个人而言,如果克隆比任何其他复制方式都慢,我仍然会使用克隆,因为它更容易阅读,而且几乎不可能在编写时出错。
System.arrayCopy
,另一方面…你看过Sun的Arrays.copyOf()实现吗
可以看出,它在内部使用了
System.arraycopy()
,因此性能将是相同的。这些是实际结果,而不是争论。显然,您的选择将取决于要复制的数据量
class ArrayCopyDemo {
public static void main(String[] args) {
char[] copyFrom = { 'd', 'e', 'c', 'a', 'f', 'f', 'e',
'i', 'n', 'a', 't', 'e', 'd' };
char[] copyTo = new char[7];
System.arraycopy(copyFrom, 2, copyTo, 0, 7);
System.out.println(new String(copyTo));
}
}
字节[]复制性能测试
10000000次迭代40b
array.copyOfRange:135ms
systems.arraycopy:141ms
10000000次迭代1000b
array.copyOfRange:1861ms
systems.arraycopy:2211ms
10000000次迭代4000b
array.copyOfRange:6315ms
systems.arraycopy:5251ms
1000000次迭代1000000b
array.copyOfRange:15198ms
systems.arraycopy:14783ms如果您查看System.arraycopy()of和Array.copyOf()的源代码以了解性能 System.arraycopy()是C代码,它直接在数组上运行,不返回任何值,因此它的运行速度应该比array.copyOf()快得多。尽管如此,如果您需要创建一个新数组,或者如果您只需要复制操作的值,那么您必须为此创建一个新数组,设置新数组长度等。因此,您无法执行返回System.arraycopy(源,0,目标,0,长度) 对于Array.copyOf()可以做什么,它将为您创建一个新数组。您可以将Array.copyOf()的返回值分配给数组,或将其作为Array.copyOf()从方法返回返回给您一个值,而不是直接在目标数组上操作。因此,您的代码看起来会更干净。尽管如此,出于性能方面的考虑,array.copyOf()是一个泛型类型方法,它不知道将使用什么。因此,它必须调用array.newInstance()或new Object()然后将其转换为输入的数组类型
总之,出于性能考虑,请使用System.arraycopy()。对于更干净的代码,请使用Array.copyOf()。我在另一个答案中发布了这一点,但在这里可能也很有用 我知道这不是
class ArrayCopyDemo {
public static void main(String[] args) {
char[] copyFrom = { 'd', 'e', 'c', 'a', 'f', 'f', 'e',
'i', 'n', 'a', 't', 'e', 'd' };
char[] copyTo = new char[7];
System.arraycopy(copyFrom, 2, copyTo, 0, 7);
System.out.println(new String(copyTo));
}
}
String[] a = new String[baseSize]; // f.e - 10.000.000
int size = baseSize / 24;
int rem = baseSize % 24;
long start = System.currentTimeMillis();
String[][]pieces = new String[23][size];
String[] last = new String[size + rem];
for (int i = 0; i < 23; i++)
System.arraycopy(a, (size * i), pieces[i], 0 , size);
System.arraycopy(a, (size * 23), last, 0 ,(size) + rem);
long elapsed = System.currentTimeMillis() - start;
long start = System.currentTimeMillis();
String[][] pieces = new String[23][];
for (int i = 0; i < 23; i++)
pieces[i] = Arrays.copyOfRange(a, size * i, size * (i + 1));
String[] last = Arrays.copyOfRange(a, size * 23, (size * 24) + rem);
long elapsed = System.currentTimeMillis() - start;