自动装箱对原始包装器的ArrayList的性能影响

时间:2015-07-09 19:31:13

标签: java collections performance-testing primitive autoboxing

Java不允许我们直接创建ArrayList基元。但是我们可以创建一个ArrayList原语包装类。

但是当访问原始值时,编译器会自动执行包装和解包。这不是开销吗?我的问题是这对性能有何影响?

在这种情况下,int[]的表现不会比ArrayList<Integer>更好吗?

有人测量int[]ArrayList<Inetger>的性能Java5.0(首次推出时)和后期版本的Java。如果您可以分享测试结果,那么遇到这个问题的每个人都会非常有帮助。

3 个答案:

答案 0 :(得分:3)

确实增加了一些开销。如果这对您来说是个问题,请考虑使用一些支持开箱即用的基元库。例如TroveGuava或google另一个图书馆

答案 1 :(得分:2)

库中的原始集合(如 Eclipse CollectionsFastUtilTroveHPPC)将节省您的内存,并且通常比它们在 Java 中的盒装等价物表现更好。每个库都将提供比 int[] 更丰富的方法集。最好根据您的特定用例比较性能。

我发现这篇 Baeldung 文章标题为“Performance Comparison of Primitive Lists in Java”,它比较了 FastUtil、Trove 和 Colt 原始列表。

Eclipse Collections 开源库有几个原始集合,包括 ListSetBagStackMap,支持所有原始类型.已经有几篇文章用性能基准来比较 JDK 集合与 Eclipse 集合原始集合的性能。

NatTable 文章对 int[]List<Integer> 进行了一些比较。

注意:我是 Eclipse Collections 的提交者

答案 2 :(得分:0)

有关20M元素int[]ArrayList(我在计算机上重新运行,来自@Wsl_F问题)的以下基准测试结果,对{p> A question提出了同一主题的问题:

public static void main(String[] args) {
    int n = 20_000_000;
    System.out.println("Warming up...");
    list(n);
    array(n);
    long t0 = System.nanoTime();
    int v = list(n);
    t0 = System.nanoTime() - t0;
    System.out.printf("list %.1f ms (%d)\n", (t0 / 1000000.0), v);

    t0 = System.nanoTime();
    v = array(n);
    t0 = System.nanoTime() - t0;
    System.out.printf("array %.1f ms (%d)\n", (t0 / 1000000.0), v);
}

private static int list(int n) {
    ArrayList<Integer> list = new ArrayList<>(n);
    for (int i = 0; i < n; i++)
        list.add(i);
    return list.get(n/2);
}

private static int array(int n) {
    int[] list = new int[n];
    for (int i = 0; i < n; i++)
        list[i] = i;
    return list[n/2];
}

给我(使用Intel Core i7的Ubuntu 16.04 x64上的Eclipse):

list 1839,9 ms (10000000)
array 515,9 ms (10000000)