【问题标题】:are arrays faster than arraylist? [duplicate]数组比arraylist 快吗? [复制]
【发布时间】:2012-07-22 05:35:33
【问题描述】:

我的直觉说数组比数组列表更快,因为数组列表是使用数组实现的,数组在填充/丢失元素时会调整大小。

我只是想确认这是否属实,这意味着如果您知道要保存的元素数量,就没有理由使用数组列表。

【问题讨论】:

  • 如果可以保证,出于性能原因,您可以继续使用数组。但是,我只会在您知道这是性能瓶颈的情况下这样做,因为这会使您的代码不那么灵活。过早的优化是万恶之源。

标签: java arrays performance arraylist


【解决方案1】:

任何性能差异都可以忽略不计,especially if you initialize your arraylist with an initialCapacity。以任何方式编写代码,使其最易读和维护,并尽量不要优化这样的东西,除非你通过测试确定你会从中获得显着的性能影响。

使用ArrayList的潜在原因:

  • 有用的方法(contains等)
  • 实现了IterableCollectionList,因此可用于许多基于接口的API调用。
  • 即使您目前“知道”收藏的大小永远不会改变,但生活对我们提出了意想不到的要求。既然没有明显的优势,为什么还要将自己锁定在一种模式中?

【讨论】:

  • 性能不容忽视。我按周期付费=P
  • @b1naryatr0phy 能否详细解释一下循环部分?
  • @Peter:当你说 CPU 是 2GHz 时,这意味着它每秒可以执行 20 亿次数学运算——或者换句话说,CPU 每十亿分之一秒“循环”一次. b1narytr0phy 开玩笑说,他的报酬是根据他的代码所需的这些“周期”的多少。
【解决方案2】:

ArrayList 为您提供了许多原始数组所没有的功能。如果您知道元素的数量,您可以创建该大小的 ArrayList。

new ArrayList<String>(100);

如果您担心 ArrayList 和数组之间的速度差异,那么您担心的是错误的事情。它极不可能成为代码中的瓶颈。如果是的话,几乎肯定有比改成数组更好的答案。

不要屈服于过早的优化。它会对你的代码造成严重破坏。大多数事情都不重要,只有少数事情重要。你只能通过分析你的代码来找到那几件事。试图使每个部分都快是使整体快的一种非常无效的方法。保持干净、简单的设计更有效。这将为您在实际需要的一两个地方引入优化提供必要的接缝。

【讨论】:

    【解决方案3】:

    ArrayList 在简单的 get/set 中不能更快,但差异会非常小,几乎在任何实际情况下都不值得担心。

    List API 有一些您可能需要的方法,即使您已经知道大小是固定的。以contains() 为例。在您需要 Iterator 或 API 需要 List 的情况下,您还必须使用 ArrayList - 即使您知道列表是固定大小的,也是如此。

    【讨论】:

      【解决方案4】:

      正如其他人已经说过的,使用 ArrayList 除非性能基准表明它是一个瓶颈。

      是的,由于访问器开销,存在性能差异,这通常不会显着。该一般规则的一个例外是,如果您在 ArrayList 中存储原始类型。这将在将对象转换为 Object 和原始类型/从 Object 和原始类型转换时对性能造成重大影响。

      // easier to work with but slow
      ArrayList<Double> slowList;
      
      // faster primitive data array
      double[] fasterList;
      

      【讨论】:

        【解决方案5】:

        是的,数组要快得多。如果您运行数值算法,您会看到明显的加速。

        但是,对于正常的应用程序而言,您不必担心。这是因为无论如何,大部分运行时都花在做其他事情上。

        【讨论】:

          【解决方案6】:

          如果您知道数组的大小,请确保它不会扩大或缩小。比使用数组。如果您不知道,数组列表更可取且稳定。对于性能,这是您唯一关心的问题吗?继续前进..

          【讨论】:

            【解决方案7】:

            您不应该过早优化您的代码,而应使用最适合您的代码的数据结构。 正如您所说,经验法则可能是:

            1. 我不知道元素的数量,或者它正在发生很大变化 => 列表(不要专注于实现)

            2. 元素的数量是预先确定的 => 数组

            【讨论】:

            • 我认为过早的优化经验法则不适用于 API 更改决策
            • @aetheria 该规则适用于黑盒函数的主体,其中优化不会影响程序的其他部分,因此您只能在拥有可以分析的工作程序时从优化中受益.在 API 中,虽然您仍然可以从分析数据中受益,但优化可能影响程序的其他部分。例如,如果他有一个返回数组`ArrayList, and he wants to switch, he has to change code that uses that function, and if that code returns that array`ArrayList 的函数,他必须更改使用该代码的代码等等。
            • 我不同意;如果没有大量的分析数据和强大的业务案例,就无法为优化目的而牺牲 API 的可用性。即便如此,几乎可以肯定有更好的方法来解决这种情况——例如以“告诉,不问”的方式设计 API,这样实现决策就更隐蔽了。这并不是说数组不容易使用。如果他们提高了 API 的可用性,那很好。如果您将它们纯粹用于优化,并因此使 API 更难使用,在我看来,这是一个糟糕的举动。
            • @aetheria 大多数体面的语言都允许隐藏实现细节——这是更好的选择。但我们不是在谈论体面的语言——我们在这里谈论的是 Java。在 Java 中,数组不与更复杂的集合共享接口(如在 C# 中),泛型不足以同时处理数组和ArrayList(如在 C++ 中),并且您不能使用类型推断来隐藏这些细节(如在 D 中)。 Java 甚至没有 typedefalias 来掩盖您实际使用的类型。
            • 我不想卷入语言战争。 Java 允许您隐藏技术细节。它还允许您显示它们。我的意思是,当你开发 API 时,最好不要透露实现细节。如果没有充分的理由,您绝对不想这样做。 “我认为它会更快”不是一个好理由。
            【解决方案8】:

            数组比数组列表快得多。差异可能有数百个百分点,并且可能来自 JVM 优化。如果您将数组变量声明为 volatile,您将获得类似的性能。

            【讨论】:

              猜你喜欢
              • 2011-09-05
              • 2018-09-28
              • 2015-01-04
              • 1970-01-01
              • 2021-05-31
              • 2015-11-10
              • 1970-01-01
              • 2013-05-29
              • 1970-01-01
              相关资源
              最近更新 更多