Java:防御性复制int[]的最有效方法是什么?

6
我有一个名为的接口,其中包含一个方法。
int[] getRawData();

出于各种原因(主要是因为我在MATLAB中使用它,而MATLAB可以很好地处理int[]),我需要返回一个数组而不是列表。

我不希望我的实现类返回int[]数组,因为它是可变的。复制int[]数组的最有效方式是什么(长度在1000-1000000范围内)?是使用clone()吗?

3个回答

7
唯一的替代方案是Arrays#copyOf()(它在内部使用System#arrayCopy())。
只需测试。
package com.stackoverflow.q2830456;

import java.util.Arrays;
import java.util.Random;

public class Test {

    public static void main(String[] args) throws Exception {
        Random random = new Random();
        int[] ints = new int[100000];
        for (int i = 0; i < ints.length; ints[i++] = random.nextInt());

        long st = System.currentTimeMillis();
        test1(ints);
        System.out.println(System.currentTimeMillis() - st);

        st = System.currentTimeMillis();
        test2(ints);
        System.out.println(System.currentTimeMillis() - st);
    }

    static void test1(int[] ints) {
        for (int i = 0; i < ints.length; i++) {
            ints.clone();
        }
    }

    static void test2(int[] ints) {
        for (int i = 0; i < ints.length; i++) {
            Arrays.copyOf(ints, ints.length);
        }
    }

}
20203
20131

当交换test1()test2()时:

20157
20275

差异可以忽略不计。我建议使用clone(),因为它更易读,并且Arrays#copyOf()仅适用于Java 6。

注:实际结果可能取决于平台和使用的JVM,这是在Dell Latitude E5500上测试的,配备Intel P8400,4GB PC2-6400 RAM,WinXP,JDK 1.6.0_17_b04。


1
@jonathan:可能取决于所使用的平台和JVM。 - BalusC
现在你忘记了导入java.util.Random; :) 下载了jdk并测试了-16140和17047在我的电脑上。似乎克隆对我来说更快...但不是快2倍。 - jonathanasdf
建议如下编写程序:static void test1(int[] ints, int reps) { for (int i = 0; i < reps; i++) { ints.clone(); } } //类似地,编写test2 - Jason S
@Stephen:这正是我在交换方法时添加结果的原因。 - BalusC
2
伙计们,微基准测试比这要难得多。我不会相信这些结果。http://code.google.com/p/caliper/wiki/JavaMicrobenchmarks - Kevin Bourrillion
显示剩余5条评论

7
  1. 通过更改arraycopy()调用为clone()或反之,无法解决任何应用程序的性能问题。

  2. 这个问题没有一个明确的答案。不仅可能在不同的虚拟机、版本、操作系统和硬件上有所不同:它确实是不同的。

  3. 无论如何,我已经在最近的OpenJDK(在最近的ubuntu上)上进行了基准测试,并发现arraycopy比较快。那么这是我的回答吗?不是!因为如果证明事实是如此,那么Arrays.copyOf的内省存在错误,而且这个错误很可能会得到修复,因此这些信息对您来说只是暂时的。


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接