【发布时间】:2010-05-13 21:29:53
【问题描述】:
我有一个带有方法的接口DataSeries
int[] getRawData();
由于各种原因(主要是因为我在 MATLAB 中使用它,并且 MATLAB 处理 int[] 很好)我需要返回一个数组而不是一个列表。
我不希望我的实现类返回 int[] 数组,因为它是可变的。复制 int[] 数组(长度在 1000-1000000 范围内)的最有效方法是什么?是clone()吗?
【问题讨论】:
我有一个带有方法的接口DataSeries
int[] getRawData();
由于各种原因(主要是因为我在 MATLAB 中使用它,并且 MATLAB 处理 int[] 很好)我需要返回一个数组而不是一个列表。
我不希望我的实现类返回 int[] 数组,因为它是可变的。复制 int[] 数组(长度在 1000-1000000 范围内)的最有效方法是什么?是clone()吗?
【问题讨论】:
唯一的选择是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() 交换时:
差异可以忽略不计。我会说,选择clone(),因为它可读性更好,而Arrays#copyOf() 仅适用于 Java 6。
注意:实际结果可能取决于所使用的平台和 JVM,这是在带有 Intel P8400、4GB PC2-6400 RAM、WinXP、JDK 1.6.0_17_b04 的 Dell Latitude E5500 上测试的
【讨论】:
Random#nextint() 填充每个int 会产生20046 和20032 毫秒。没有明显区别。
从来没有人通过将 arraycopy() 调用更改为 clone() 来解决他们应用程序的性能问题,反之亦然。
这个问题没有一个明确的答案。这不仅仅是因为它可能在不同的虚拟机、版本、操作系统和硬件上有所不同:它真的是不同的。
无论如何,我在最近的 OpenJDK(在最近的 ubuntu 上)上对其进行了基准测试,发现 arraycopy 的速度要快得多。这是我给你的答案吗?不!因为如果它被证明是真的,那么就有一个带有 Arrays.copyOf 内在化的 bug,而且这个 bug 很可能会得到修复,所以这些信息对你来说只是暂时的。
【讨论】:
http://www.javapractices.com/topic/TopicAction.do?Id=3
根据您的规格,数字可能会有所不同,但似乎克隆是最佳选择。
【讨论】: