填充ArrayList与LinkedList

时间:2014-10-16 12:19:20

标签: java arraylist linked-list performance-testing microbenchmark

我一直认为LinkedList的填充速度比ArrayList快。据我所知ArrayList基于有限长度(常数)的简单数组。因此,每次数组超出范围时,都会创建具有更高范围的新数组。 LinkedList要简单得多。它没有任何限制(内存除外),因此应该更快填充。但我运行下一个代码:

 public static void main(String[] args) {
        int length = 7000000;

        List<Integer> list = new LinkedList<Integer>();
        long oldTime = System.currentTimeMillis();
        for (int i = 0; i < length; i++) {
            list.add(i);
        }
        System.out.println("LinkedList fill: " + (System.currentTimeMillis() - oldTime));

        list = new ArrayList<Integer>();
        oldTime = System.currentTimeMillis();
        for (int i = 0; i < length; i++) {
            list.add(i);
        }
        System.out.println("ArrayList fill: " + (System.currentTimeMillis() - oldTime));
    }

输出结果为:

LinkedList fill: 3936
ArrayList fill: 628

为什么会这样?

1 个答案:

答案 0 :(得分:2)

你无法像Java那样对性能进行真正的基准测试。有关可能出错的许多内容的更详细说明,请参阅How do I write a correct micro-benchmark in Java?

如果我test your code jmh,我会得到以下结果:

Benchmark                      Mode  Samples  Score   Error  Units
c.a.p.SO26404256.arrayList     avgt        5  7.661 ± 0.672  ms/op
c.a.p.SO26404256.linkedList    avgt        5  9.675 ± 1.213  ms/op

因此填充LinkedList似乎比填充arrayList稍慢,但差别远小于测试所示的差异。

至于差异的原因,可能是因为LinkedList的每个元素都包含在Node中:这意味着更多的对象创建和更多的垃圾收集。而由于ArrayList中的数组副本导致的惩罚可能比你想象的要小,因为它们是高度优化的。