Java List vs Array []。以前的线程说使用列表,我不相信。

时间:2014-01-08 15:59:37

标签: java arrays list performance

我已经阅读了之前关于此事的一些帖子。参数是列表更容易使用,更灵活。

我之前的所有经验都向我展示了灵活性是一种成本。

我正在设计的程序大量使用列表。我有映射到列表的列表,这些列表被比较,追加和搜索(哦,我的!)。

很容易附加两个列表。 listA.appendAll(数组listB)。

几乎同样容易追加两个数组。只需创建一个两者大小的新数组并复制它们。

现在,当这些操作按照成千上万的顺序完成时,我的直觉告诉我,阵列将是一个相当不错的选择。当然,我更倾向于使用列表,但不是以牺牲性能为代价

我的直觉本能是正确的,还是真正像数组一样有效的列表?我理解ArrayLists如何使容量增加一倍来增加平均值~O(N),但我需要最有效的选择。

3 个答案:

答案 0 :(得分:8)

你的直觉几乎总是错误的(如果你肯定知道,你不需要听你的胆量,如果你不知道,你的决定大多是随机的。)

今天的问题不在于列表的效率如何,问题是:您需要多少内存以及您可以分配多少时间来寻找优化(但遗憾的是稍微损坏)代码中的错误?

数百万人正在使用ArrayList,这是一种安全,经过验证,快速可靠的技术。添加其中两个几乎与使用两个本机数组手动执行速度一样快但是a)它只是 me 的一行代码,b)它涵盖了所有角落情况和c)是否应该真的太慢了​​,我可以让我的探测器找到一些太慢而且修复它们的地方(而不是让我的生活在一千个不太重要的地方让我痛苦不堪)。

除此之外,由于ArrayList是如此繁重的使用类型,因此Java编译器和JIT已针对死亡进行了优化以使其快速生成。因此,即使它看起来更像是代码,它实际上可能比你手动编写的任何代码都要快,因为JIT无法识别你的代码并将其优化为积极的代码。

最后,您可以轻松编写自己的ArrayList以使用更有效的分配算法。如果您在任何地方使用List界面编写代码,最终只能在一个地方优化您需要的内容,以便在任何地方都能更快地完成。

或者可以使用新的Array接口以及您需要的2-3个操作。这样,您可以轻松创建2-3个不同优化目标的实现,并相应地使用它们。

根据我的经验,最糟糕的解决方案是将代码洒入4-10行本机阵列操作(比如需要附加两个数组的四行)。至少在公共帮助程序类中移动此类代码,并确保使用单元测试覆盖所有角落情况。

答案 1 :(得分:2)

我的直觉本能是正确的,还是真正像数组一样有效的列表?
两者都没有。列表并不像Arrays那样“真正”有效(尽管ArrayLists很接近),但这并不意味着任何优化都必然会超过灵活性的好处,即使你有数千个操作正在进行

考虑以下问题:

  • 这个应用程序需要真的,非常快吗?
  • 使用数组或列表的代码部分是否永远不会被进一步开发?

如果这两个问题的答案都是,那么请使用数组。否则,请使用列表。

但是由于数组和列表之间的性能(特别是ArrayList实现)并没有那么多,并且因为你的代码很可能进一步开发......
... 只使用列表

答案 2 :(得分:1)

ArrayList由数组支持,所以没有测试我觉得它们的效率可能很接近。如果您知道数组的大小,只需使用初始大小构造ArrayList,以减少增加大小的开销。

  public ArrayList(int initialCapacity) {
     super();
     if (initialCapacity < 0)
         throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
     this.elementData = new Object[initialCapacity];
 }

ArrayList.addAll ArrayList实现看起来像你可能想出的东西

    public boolean addAll(Collection<? extends E> c) {
     Object[] a = c.toArray();
     int numNew = a.length;
     ensureCapacity(size + numNew);  // Increments modCount
     System.arraycopy(a, 0, elementData, size, numNew);
     size += numNew;
     return numNew != 0;
 }

奇怪的是,如果你自己制作数组,你可能会最终制作一个辅助方法来完成ArrayList已经实现的大部分内容。不要重新发明轮子