1. 引言

在Java编程语言中,数组(/java-convert-string-array-to-int-array)和列表(/java-arraylist)是存储元素集合的两种主要数据结构。

数组和列表各有优缺点,选择合适的数据结构取决于我们应用场景的具体需求。

在这篇教程中,我们将探讨Java中数组和列表在性能上的差异,并使用Java微基准测试框架(/java-microbenchmark-harness)进行测试示例对比。

2. 创建新对象的性能

让我们通过一个简单的Java示例来比较数组和ArrayList创建的性能:

@Benchmark
public Integer[] arrayCreation() {
    return new Integer[256];
}

@Benchmark
public ArrayList<Integer> arrayListCreation() {
    return new ArrayList<>(256);
}

以下表格显示了创建数组和ArrayList所需的时间(单位:纳秒):

基准

模式 计数 时间 错误 单位
数组 - 创建 平均值 202.909 2.135 ns/op
列表 - 创建 平均值 231.565 103.332 ns/op

结果显示,创建数组(202.909 ns/op)的平均时间明显快于创建ArrayList(231.565 ns/op)。

3. 添加项目的性能

接下来,我们比较在数组和ArrayList中添加项目的性能:

@Benchmark
public Integer[] arrayItemsSetting() {
    for (int i = 0; i < 256; i++) {
        array[i] = i;
    }
    return array;
}

@Benchmark
public ArrayList<Integer> arrayListItemsSetting() {
    for (int i = 0; i < 256; i++) {
        list.add(i);
    }
    return list;
}

以下是设置数组和ArrayList中项目值所需的时间(单位:纳秒):

基准

模式 计数 时间 错误 单位
数组 - 添加 平均值 2587.040 671.391 ns/op
列表 - 添加 平均值 2269.738 906.403 ns/op

基准测试结果显示,将项目设置到数组中(2587.040 ns/op)的平均时间比创建ArrayList(2269.738 ns/op)慢。

4. 获取项目值的性能

现在,让我们比较从数组和ArrayList中获取项目值的性能:

@Benchmark
public void arrayItemsRetrieval(Blackhole blackhole) {
    for (int i = 0; i < 256; i++) {
        int item = array[i];
        blackhole.consume(item);
    }
}

@Benchmark
public void arrayListItemsRetrieval(Blackhole blackhole) {
    for (int i = 0; i < 256; i++) {
        int item = list.get(i);
        blackhole.consume(item);
    }
}

以下是获取数组和ArrayList中项目值所需的时间(单位:纳秒):

基准

模式 计数 时间 错误 单位
数组 - 获取 平均值 163.559 13.503 ns/op
列表 - 获取 平均值 261.106 5.371 ns/op

数组的项目获取时间更快,为(163.559 ns/op),而ArrayList由于需要对底层数组进行额外检查,其获取时间较长,为(261.106 ns/op)。

请注意,这个基准测试是在Open JDK 17.0.2上运行的。

5. 克隆/复制的性能

最后,我们比较数组和ArrayList的克隆/复制性能:

@Benchmark
public void arrayCloning(Blackhole blackhole) {
    Integer[] newArray = array.clone();
    blackhole.consume(newArray);
}

@Benchmark
public void arrayListCloning(Blackhole blackhole) {
    ArrayList<Integer> newList = new ArrayList<>(list);
    blackhole.consume(newList);
}

以下是克隆/复制数组和ArrayList所需的时间(单位:纳秒):

基准

模式 计数 时间 错误 单位
数组 - 克隆 平均值 204.608 5.270 ns/op
列表 - 克隆 平均值 232.177 80.040 ns/op

数组的克隆速度明显快于ArrayList,因为数组创建涉及的是更简单的连续内存分配操作。相比之下,ArrayList的创建包括初始化内部数据结构和随着元素添加动态调整列表大小等额外开销。

请记住,实际性能可能因集合大小、执行代码的硬件以及使用的Java版本等因素而变化。

6. 总结

总之,本文比较了Java中数组和列表的性能。然而,实际性能可能会根据集合大小和硬件环境有所不同。

完整的示例代码可在GitHub上找到。