1. 概述

在本教程中,我们将 对几种流行的 Java 原生类型集合库进行性能对比测试

具体来说,我们会分别测试这些库中 add()get()contains() 方法的执行效率。

2. 性能对比分析

接下来,我们来看看哪个库提供了更高效的原生集合 API。

为此,我们选取了 Trove、Fastutil 和 Colt 这三个库中的 List 类型,并使用 JMH(Java Microbenchmark Harness) 工具来进行基准测试。

2.1. JMH 参数设置

我们的基准测试将使用如下配置参数:

@BenchmarkMode(Mode.SingleShotTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Measurement(batchSize = 100000, iterations = 10)
@Warmup(batchSize = 100000, iterations = 10)
@State(Scope.Thread)
public class PrimitivesListPerformance {
}

说明如下:

  • 使用 @BenchmarkMode(Mode.SingleShotTime) 来测量每次操作的时间。
  • 结果以毫秒为单位输出。
  • 测试和预热阶段都运行 10 次,每次批量处理 100,000 个元素。
  • @State(Scope.Thread) 表示每个线程拥有独立的状态实例。

此外,我们定义并初始化各个集合对象:

public static class PrimitivesListPerformance {
    private List<Integer> arrayList = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
    private TIntArrayList tList = new TIntArrayList(new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
    private cern.colt.list.IntArrayList coltList = new cern.colt.list.IntArrayList(new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
    private IntArrayList fastUtilList = new IntArrayList(new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9});

    private int getValue = 4;
}

现在可以开始编写基准测试方法了。

3. add() 方法性能

首先测试向集合中添加元素的操作。我们也会测试标准的 ArrayList 作为参照。

3.1. 基准测试代码

标准 ArrayList 的添加操作:

@Benchmark
public boolean addArrayList() {
    return arrayList.add(getValue);
}

Trove 的 TIntArrayList.add()

@Benchmark
public boolean addTroveIntList() {
    return tList.add(getValue);
}

Colt 的 IntArrayList.add()

@Benchmark
public void addColtIntList() {
    coltList.add(getValue);
}

Fastutil 的 IntArrayList.add()

@Benchmark
public boolean addFastUtilIntList() {
    return fastUtilList.add(getValue);
}

3.2. 测试结果

运行测试后得到以下结果:

Benchmark           Mode  Cnt  Score   Error  Units
addArrayList          ss   10  4.527 ± 4.866  ms/op
addColtIntList        ss   10  1.823 ± 4.360  ms/op
addFastUtilIntList    ss   10  2.097 ± 2.329  ms/op
addTroveIntList       ss   10  3.069 ± 4.026  ms/op

从结果可以看出:

ArrayList.add() 是最慢的,因为它涉及装箱/拆箱操作。

⚠️ 虽然三款原生集合库底层都使用 int[] 存储数据,但 Colt 在 add() 操作上表现最好。

原因在于:

  • Colt 只在数组满时才扩容;
  • Trove 和 Fastutil 扩容时会做额外计算,因此稍慢一些。

4. get() 方法性能

接下来测试获取元素的性能。

4.1. 基准测试代码

ArrayList.get()

@Benchmark
public int getArrayList() {
    return arrayList.get(getValue);
}

Trove 的 TIntArrayList.get()

@Benchmark
public int getTroveIntList() {
    return tList.get(getValue);
}

Colt 的 IntArrayList.get()

@Benchmark
public int getColtIntList() {
    return coltList.get(getValue);
}

Fastutil 的 IntArrayList.getInt()

@Benchmark
public int getFastUtilIntList() {
    return fastUtilList.getInt(getValue);
}

4.2. 测试结果

Benchmark           Mode  Cnt  Score   Error  Units
getArrayList        ss     20  5.539 ± 0.552  ms/op
getColtIntList      ss     20  4.598 ± 0.825  ms/op
getFastUtilIntList  ss     20  4.585 ± 0.489  ms/op
getTroveIntList     ss     20  4.715 ± 0.751  ms/op

ArrayList.get() 略慢于其他原生集合库。

✅ 三款原生集合库的实现几乎一致,都是直接从内部数组中取值,所以性能接近。

5. contains() 方法性能

最后测试查找元素是否存在。

5.1. 基准测试代码

ArrayList.contains()

@Benchmark
public boolean containsArrayList() {
    return arrayList.contains(getValue);
}

Trove 的 TIntArrayList.contains()

@Benchmark
public boolean containsTroveIntList() {
    return tList.contains(getValue);
}

Colt 的 IntArrayList.contains()

@Benchmark
public boolean containsColtIntList() {
    return coltList.contains(getValue);
}

Fastutil 的 IntArrayList.contains()

@Benchmark
public boolean containsFastUtilIntList() {
    return fastUtilList.contains(getValue);
}

5.2. 测试结果

Benchmark                  Mode  Cnt   Score    Error  Units
containsArrayList          ss     20   2.083  ± 1.585  ms/op
containsColtIntList        ss     20   1.623  ± 0.960  ms/op
containsFastUtilIntList    ss     20   1.406  ± 0.400  ms/op
containsTroveIntList       ss     20   1.512  ± 0.307  ms/op

ArrayList.contains() 依旧是最慢的,因为需要频繁装箱/拆箱。

✅ 其他三个库的表现非常接近,选择哪个主要看项目需求和生态支持。

6. 小结

在这篇文章中,我们通过 JMH 对多个 Java 原生集合库进行了基准测试,比较了它们与标准 ArrayListadd()get()contains() 操作上的性能差异。

📌 请注意:这里展示的只是基准测试的结果,在实际项目中请务必结合自己的业务场景进行实测。

如需查看完整代码,请访问:GitHub - core-java-collections-list-3


原始标题:Performance Comparison of Primitive Lists in Java