为什么 clone() 是复制数组的最佳方式? [英] Why clone() is the best way for copying arrays?

查看:34
本文介绍了为什么 clone() 是复制数组的最佳方式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这对我来说是一种耻辱,但我不知道:

It's a shame for me, but I did not know that:

你应该使用 clone 来复制数组,因为这通常是最快的方法.

You should use clone to copy arrays, because that's generally the fastest way to do it.

正如 Josh Bloch 在此博客中所述:http://www.artima.com/intv/bloch13.html

as Josh Bloch states in this blog: http://www.artima.com/intv/bloch13.html

我一直使用System.arraycopy(...).这两种方法都是原生的,所以可能没有更深入地了解库的来源,我无法弄清楚,为什么会这样.

I always used System.arraycopy(...). Both approaches are native, so probably without going deeper into the sources of libraries I can not figure out, why it is so.

我的问题很简单:为什么是最快方式?System.arraycopy有什么区别?此处解释了区别,但它没有回答为什么 Josh Bloch 认为 clone() 是最快的方法.

My question is simple: why is it the fastest way? What is the difference with System.arraycopy? The difference is explained here, but it does not answer the question why Josh Bloch considers clone() as the fastest way.

推荐答案

我想说明为什么 clone() 是复制数组最快的方法,而不是 System.arraycopy(..) 或其他:

I would like to make some points about why clone() is the fastest way to copy an array than System.arraycopy(..) or others:

1. clone() 在将源数组复制到目标数组之前不必进行类型检查 此处.它只是简单地分配新的内存空间并将对象分配给它.另一方面,System.arraycopy(..) 检查类型,然后复制一个数组.

1. clone() doesn't have to do the typechecking before copying a source array to the destination one as provided here. It just simple allocates new memory space and assigns the objects to it. On the other hand, System.arraycopy(..) checks for the type and then copies an array.

2. clone() 也打破了优化以消除冗余归零.如您所知,Java 中每个分配的数组都必须使用 0s 或相应的默认值进行初始化.但是,如果 JIT 发现该数组在创建后立即被填充,则它可以避免将该数组清零.与使用现有 0s 或相应的默认值更改副本值相比,这绝对更快.在使用 System.arraycopy(..) 时,会花费大量时间来清除和复制已初始化的数组.为此,我进行了一些基准测试.

2. clone() also breaks the optimization to eliminate redundant zeroing. As you know, every allocated array in Java must be initialized with 0s or respective default values. However, JIT can avoid zeroing this array if it sees that the array is filled right after creation. That makes it definitely faster compared to changing the copy values with existing 0s or respective default values. While using System.arraycopy(..) spends significant amount of time clearing and copying the initialized array. To do so I have performed some of the benchmark tests.

@BenchmarkMode(Mode.Throughput)
@Fork(1)
@State(Scope.Thread)
@Warmup(iterations = 10, time = 1, batchSize = 1000)
@Measurement(iterations = 10, time = 1, batchSize = 1000)
public class BenchmarkTests {

    @Param({"1000","100","10","5", "1"})
    private int size;
    private int[] original;

    @Setup
    public void setup() {
        original = new int[size];
        for (int i = 0; i < size; i++) {
            original[i] = i;
        }
    }

    @Benchmark
    public int[] SystemArrayCopy() {
        final int length = size;
        int[] destination = new int[length];
        System.arraycopy(original, 0, destination, 0, length);
        return destination;
    }


    @Benchmark
    public int[] arrayClone() {
        return original.clone();
    }

}

输出:

Benchmark                        (size)   Mode  Cnt       Score      Error  Units
ArrayCopy.SystemArrayCopy            1  thrpt   10   26324.251 ± 1532.265  ops/s
ArrayCopy.SystemArrayCopy            5  thrpt   10   26435.562 ± 2537.114  ops/s
ArrayCopy.SystemArrayCopy           10  thrpt   10   27262.200 ± 2145.334  ops/s
ArrayCopy.SystemArrayCopy          100  thrpt   10   10524.117 ±  474.325  ops/s
ArrayCopy.SystemArrayCopy         1000  thrpt   10     984.213 ±  121.934  ops/s
ArrayCopy.arrayClone                 1  thrpt   10   55832.672 ± 4521.112  ops/s
ArrayCopy.arrayClone                 5  thrpt   10   48174.496 ± 2728.928  ops/s
ArrayCopy.arrayClone                10  thrpt   10   46267.482 ± 4641.747  ops/s
ArrayCopy.arrayClone               100  thrpt   10   19837.480 ±  364.156  ops/s
ArrayCopy.arrayClone              1000  thrpt   10    1841.145 ±  110.322  ops/s

根据输出,我得到 clone 的速度几乎是 System.arraycopy(..)

According to the outputs I am getting that clone is almost twice fast from System.arraycopy(..)

3.此外,使用像 clone() 这样的手动复制方法会导致更快的输出,因为它不必进行任何 VM 调用(不像 System.arraycopy()).

3. Also, using manual copying method like clone() results into faster ouput because it doesn't have to make any VM calls (unlike System.arraycopy()).

这篇关于为什么 clone() 是复制数组的最佳方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆