猿问

什么是更有效的:System.arraycopy或Arrays.copyOf?

,Bloch中的toArray方法ArrayList同时使用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;

}

如何比较这两种复制方法,何时应使用哪种复制方法?


杨魅力
浏览 726回答 3
3回答

慕虎7371278

不同之处在于Arrays.copyOf不仅复制元素,还创建新的数组。System.arraycopy复制到现有阵列中。这是的来源Arrays.copyOf,您可以看到它在System.arraycopy内部用于填充新数组:public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {&nbsp; &nbsp; T[] copy = ((Object)newType == (Object)Object[].class)&nbsp; &nbsp; &nbsp; &nbsp; ? (T[]) new Object[newLength]&nbsp; &nbsp; &nbsp; &nbsp; : (T[]) Array.newInstance(newType.getComponentType(), newLength);&nbsp; &nbsp; System.arraycopy(original, 0, copy, 0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Math.min(original.length, newLength));&nbsp; &nbsp; return copy;}

忽然笑

虽然System.arraycopy是本地实现的,因此可能比Java循环快1,但它并不总是像您期望的那样快。考虑以下示例:Object[] foo = new Object[]{...};String[] bar = new String[foo.length];System.arraycopy(foo, 0, bar, 0, bar.length);在这种情况下,fooand bar数组具有不同的基本类型,因此实现arraycopy必须检查复制的每个引用的类型,以确保它实际上是对String实例的引用。这比简单的C样式memcopy的数组内容要慢得多。另一点是在引擎盖下Arrays.copyOf使用System.arraycopy。因此System.arraycopy是在它的脸上不应该慢2比Arrays.copyOf。但是你可以看到(转引自码以上),其Arrays.copyOf在某些情况下会使用反射来创建新的数组。因此,性能比较并不简单。此分析有两个缺陷。我们正在查看特定Java版本的实现代码。这些方法可能会更改,从而使先前有关效率的假设无效。我们忽略了JIT编译器可以对这些方法进行一些巧妙的特殊情况优化的可能性。显然这确实是发生了Arrays.copyOf; 请参阅为什么小型阵列的Arrays.copyOf比System.arraycopy快2倍?。在当前的Java实现中,该方法是“固有的”,这意味着JIT编译器将忽略Java源代码中的内容!但是,无论哪种方式,两个版本之间的差异都是O(1)(即与数组大小无关)且相对较小。因此,我的建议是使用使您的代码最容易阅读的版本,并且仅在概要分析告诉您这很重要时才担心哪个版本更快。1- 可能更快,但是JIT编译器也可能在优化手动编码循环方面做得很好,没有区别。

慕码人8056858

如果要精确地复制数组(例如,如果要进行防御性复制),则复制数组的最有效方法可能是使用数组对象的clone()方法:class C {&nbsp; &nbsp; private int[] arr;&nbsp; &nbsp; public C(int[] values){&nbsp; &nbsp; &nbsp; &nbsp; this.arr = values.clone();&nbsp; &nbsp; }}我没有费心去测试它的性能,但是它是个非常快的好机会,因为它是纯本地的(分配和复制在调用中),克隆是一种特殊的JVM祝福的复制对象的方式(而且(大多数用于其他目的是邪恶的),并且很可能能够采取一些“捷径”。就个人而言,clone如果它比其他任何复制方式都慢,我仍然会使用它,因为它更容易阅读,几乎不可能在书写时弄乱。System.arrayCopy, 另一方面...
随时随地看视频慕课网APP

相关分类

Java
我要回答