【问题标题】:Java: ArrayList add() and remove() performance, implementation?Java:ArrayList add() 和 remove() 性能、实现?
【发布时间】:2011-12-16 03:40:51
【问题描述】:

我在某处读到 ArrayList 的 add()remove() 操作在“摊销常数”时间内运行。这到底是什么意思?

add(item)的实现中可以看到ArrayList使用了一个数组缓冲区,最多是list的3/2大小,如果满了,System.arraycopy() 被调用,它应该在 O(n) 时间内执行,而不是 O(1) 时间。那么 System.arraycopy 是否会尝试做一些比将元素一个一个复制到新创建的数组中更聪明的事情,因为时间实际上是 O(1)?


结论:add(item) 运行在摊销的常数时间内,但 add(item, index)remove(index) 不' t,它们以线性时间运行(如答案中所述)。

【问题讨论】:

标签: java performance collections arraylist


【解决方案1】:

“摊销”大致意思是“在整个运行时平均”。是的,数组副本将是 O(n)。但这仅在列表已满时才会发生,这种情况会在 n 次中发生 1 次。

【讨论】:

  • +1 即使我不确定“在 n 次中发生 1 次”是否合适......通常每次增加的支持都是两倍,所以......不知道删除的限制/规则是。
  • 所以,我猜这个“平均恒定时间”成立是因为缓冲区 growth 不是恒定的,而是与数组的大小成正比? (每次调整大小时数组大小的 +1/2,而不是例如每次 +5 个位置)?
【解决方案2】:

我认为摊销常数时间只是意味着如果您进行大量操作,它几乎是常数时间。因此,在一个测试中将一百万个项目添加到列表中,然后在另一个测试中将两百万个项目添加到列表中。后者应该比前者慢约 2 倍,因此,摊销常数时间。

【讨论】:

    【解决方案3】:

    摊销的常数时间不同于常数时间。

    基本上摊销 O(1) 意味着在 n 次操作中,任何操作的平均运行时间为 O(1)。

    对于数组列表,这类似于:

    (O(1) 插入 + O(1) 插入 + ... + O(n) 数组复制) / n 次操作 = O(1)

    【讨论】:

      【解决方案4】:

      我在某处读到 ArrayList 的 add() 和 remove() 操作在“摊销常数”时间内运行。

      我认为remove() 不是这样,除非是在不寻常的情况下。

      • 一个随机元素的remove(Object)调用平均必须对列表中的一半条目调用equals,然后复制另一半的引用。

      • 对随机元素的remove(int) 调用平均必须复制一半元素的引用。

      remove(...) 平均为O(1) 的唯一情况(例如摊销)是当您使用remove(int) 删除与列表末尾一些恒定偏移量的元素时。

      【讨论】:

        【解决方案5】:

        线程Constant Amortized Time中Amortized Constant含义的深入说明

        【讨论】:

          【解决方案6】:

          简述摊销时间:

          如果您进行一百万次操作,您并不真正关心该操作的最坏情况或最佳情况 - 您关心的是当您重复该操作时总共花费了多少时间一百万次。

          因此,操作是否偶尔非常缓慢并不重要,只要“偶尔”足够罕见,可以将缓慢冲淡掉。基本上摊销时间是指“每次操作所花费的平均时间,如果你做了很多操作”。摊销时间不必是恒定的;你可以有线性和对数摊销时间或其他任何东西。

          让我们以 mats 的动态数组为例,您可以在其中重复添加新项目。通常添加一个项目需要恒定的时间(即 O(1))。但每次阵列满时,您都会分配两倍的空间,将数据复制到新区域,并释放旧空间。假设分配和释放在恒定时间内运行,这个扩大过程需要 O(n) 时间,其中 n 是数组的当前大小。

          因此,每次放大时,您花费的时间大约是上次放大的两倍。但你也等了两倍的时间才这样做!因此,每次扩大的成本可以在插入之间“分摊”。这意味着从长远来看,将 m 项添加到数组中所需的总时间为 O(m),因此摊销时间(即每次插入的时间)为 O(1)。

          【讨论】:

            猜你喜欢
            • 2013-12-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多