为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

杨魅力 2019-11-26 15:28:20
,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;}如何比较这两种复制方法,何时应使用哪种复制方法?
查看完整描述

3 回答

?
慕虎7371278

TA贡献1802条经验 获得超4个赞

不同之处在于Arrays.copyOf不仅复制元素,还创建新的数组。System.arraycopy复制到现有阵列中。


这是的来源Arrays.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;

}


查看完整回答
反对 回复 2019-11-26
?
忽然笑

TA贡献1806条经验 获得超5个赞

虽然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编译器也可能在优化手动编码循环方面做得很好,没有区别。


查看完整回答
反对 回复 2019-11-26
?
慕码人8056858

TA贡献1803条经验 获得超6个赞

如果要精确地复制数组(例如,如果要进行防御性复制),则复制数组的最有效方法可能是使用数组对象的clone()方法:


class C {

    private int[] arr;

    public C(int[] values){

        this.arr = values.clone();

    }

}

我没有费心去测试它的性能,但是它是个非常快的好机会,因为它是纯本地的(分配和复制在调用中),克隆是一种特殊的JVM祝福的复制对象的方式(而且(大多数用于其他目的是邪恶的),并且很可能能够采取一些“捷径”。


就个人而言,clone如果它比其他任何复制方式都慢,我仍然会使用它,因为它更容易阅读,几乎不可能在书写时弄乱。System.arrayCopy, 另一方面...


查看完整回答
反对 回复 2019-11-26
  • 3 回答
  • 0 关注
  • 725 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信