【问题标题】:JDK8 performance of ArrayList compared to LinkedListArrayList 与 LinkedList 相比的 JDK8 性能
【发布时间】:2016-12-19 17:08:27
【问题描述】:

我开始看到越来越多的基准测试证明 ArrayList 在以下“大型”插入示例的性能方面可以碾压 LinkedList: Gluelist

Adding(1M) Elements (5 Tests Avg.)

LinkedList: 174.8 milliseconds
ArrayList:  76.4 milliseconds
GlueList:   39.2 milliseconds

Adding(10M) Elements (5 Tests Avg.)

LinkedList: 8975.6 milliseconds
ArrayList:  4118.2 milliseconds
GlueList:   3320.1 milliseconds

我使用 JDK8.latest 在 RHEL 7.2 上运行了类似的测试,并看到了类似的结果。我的印象是,即使在最坏的情况下,LinkedList 插入也是 O(1),而 ArrayList 由于复制操作而需要 > O(1)(我意识到我们可以讨论摊销成本,但这超出了范围) .我的问题是:鉴于 ArrayList 在接近容量时强制执行复制操作,LinkedList 的性能如何比 ArrayList 差?

【问题讨论】:

  • 猜测:System.arraycopy 是一个高效的、打包的memcpy,而LinkedList 插入需要大量分配并破坏缓存局部性。
  • “我意识到我们可以讨论摊销成本,但这超出了范围)” - 您正在测量摊销成本。为什么要把它排除在讨论之外?

标签: java performance arraylist linked-list


【解决方案1】:

他们有相同的大 O,但这并不能告诉你持续的关系。它告诉您它们在理想化机器上的行为,而不是真实机器。

LinkedList 分配和使用更多内存。它为每个节点创建一个 24 字节的对象,而 ArrayList(通常)每个引用使用 4 个字节,并且创建的对象要少得多。

【讨论】:

    【解决方案2】:

    Big O 并不能真正帮助您。它告诉你增长的方向,但它没有给你绝对数字。

    ArrayList 使用数组,具有高度优化的本机 System.arrayCopy() 调用。

    LinkedLists 必须为每个节点创建一个包装对象,并在其中存储指向下一个和前一个节点的指针。这需要时间。

    ArrayList 在插入时不会创建单个对象,除非它调整数组的大小,这种情况并不经常发生。

    【讨论】:

      【解决方案3】:

      还有一个问题:他们是如何测试性能的?

      编写好的微基准并不容易。

      这里有一些不错的文章:

      http://www.ibm.com/developerworks/java/library/j-benchmark1/index.html

      http://www.ibm.com/developerworks/java/library/j-benchmark2/index.html

      http://ellipticgroup.com/html/benchmarkingArticle.html

      【讨论】:

      • 我承认这一点,但在大多数情况下确实如此:ArrayList 性能更好,但有一些非常奇特的用例
      猜你喜欢
      • 2010-12-15
      • 2014-12-31
      • 2013-12-04
      • 2016-03-16
      • 1970-01-01
      • 1970-01-01
      • 2011-08-16
      • 2020-12-26
      • 2012-05-26
      相关资源
      最近更新 更多