为什么System.arraycopy在Java中是原生的?

Jam*_*s B 79 java arrays native arraycopy

我很惊讶在Java源代码中看到System.arraycopy是一个本机方法.

当然原因是因为它更快.但是什么原生技巧是能够使用的代码使其更快?

为什么不循环遍历原始数组并将每个指针复制到新数组 - 当然这不是那么缓慢和麻烦?

Pét*_*rök 75

在本机代码中,可以使用单个memcpy/ memmove而不是n个不同的复制操作来完成.性能差异很大.

  • 实际上,只有`arraycopy`的一些子类可以使用`memcpy` /`memmove`来实现.其他需要对复制的每个元素进行运行时类型检查. (7认同)
  • @PéterTörök - 考虑从填充了`String`对象的`Object []`复制到`String []`.参见http://java.sun.com/javase/6/docs/api/java/lang/System.html#arraycopy(java.lang.Object,%20int,%20java.lang.Object,%20int)的最后一段,%20int) (3认同)
  • Peter,Object []和byte [] + char []是最常复制的,它们都不需要显式类型检查.编译器非常聪明,除非需要,否则不会检查,而在99.9%的情况下,它不是.有趣的部分是小尺寸副本(小于高速缓存行)占主导地位,因此对于小尺寸的东西来说快速的"memcpy"非常重要. (3认同)

use*_*421 15

它不能用Java编写.本机代码能够忽略或忽略Object数组和基元数组之间的差异.Java无法做到这一点,至少效率不高.

由于重叠数组所需的语义,它不能用单个来编写memcpy().

  • 很好,那么'memmove`然后.虽然我不认为这个问题的背景有太大的不同. (3认同)

Tom*_*ine 9

当然,它取决于实现.

HotSpot会将其视为"内在"并在呼叫站点插入代码.那是机器代码,而不是旧C代码.这也意味着该方法签名的问题很大程度上消失了.

简单的复制循环非常简单,可以对其应用明显的优化.例如循环展开.究竟发生了什么再次依赖于实现.

  • 这是一个非常体面的答案:),尤其是。提到内在因素。没有它们,简单的迭代可能会更快,因为它通常会被 JIT 展开 (2认同)