【问题标题】:How is ArrayDeque faster than stack?ArrayDeque 如何比堆栈快?
【发布时间】:2014-07-17 11:50:14
【问题描述】:

根据javadoc,

ArrayDeque 类在用作堆栈时可能比 Stack 快

我不明白 ArrayDeque 怎么能比堆栈快。假设栈使用链表实现如下:

Push: Insert new element at the head, teamp->next = head; head = temp 
(where temp is the element to be inserted)
Pop: Remove the element from head, and make head = head->next

对于大量元素,ArrayDeque 调整大小会产生开销,而在使用 LinkedList 实现的 Stack 中不会出现这种情况。那么 ArrayDeque 到底比 stack 快多少呢?

【问题讨论】:

    标签: java stack arraydeque


    【解决方案1】:

    ArrayDeque 是 Java 集合框架的一部分,并不是为了本质上是线程安全的。

    Stack 与 Vector 和 Hashtable 一起出现在 Java 1.0 中,并通过线程安全操作实现(因为当时这似乎是个好主意)。获取和释放线程锁在时间上相对昂贵,因此这些数据结构将比它们在 JCF 中的同胞慢得多。

    【讨论】:

      【解决方案2】:

      因为大多数操作不需要调整数组大小,特别是当队列达到稳定大小并且不再增长时。

      每次添加项目Stack 都必须分配新对象更新链接等。

      ArrayDeque 只需要在数组中放入一个对象并更新索引即可。

      【讨论】:

      • 这是正确的吗?考虑到 Java 堆栈实际上不是使用任何链接结构实现的,而是由 OP 假设的。
      【解决方案3】:

      根据我的经验,仅在一种情况下,链表比数组列表更有效——在这种情况下,您经常希望一次通过列表中的随机点添加或删除多个元素。在其他所有情况下,数组列表通常更好——更快的查找、随机访问、更少的内存。如果 ArrayDeque 基于数组 - 它可能不需要为存储在其中的每个项目分配额外的节点对象。

      由于堆栈通常在列表末尾添加/删除项目,因此基于数组的解决方案可能更有效

      【讨论】:

      • 实际上我认为列表标准中的随机点仍然不够具体。除非您已经在遍历列表,否则ArrayList 可能仍然更快,因为在修改后的元素上洗牌并不比仅在LinkedList 中查找元素所需的列表扫描慢很多。基本上在搜索列表时修改列表或列表头部的大量操作是LinkedList 具有优势的地方。
      • @Tim B - 我已经更新了我的答案以反映这一点 - 你是对的。
      【解决方案4】:

      使用 ArrayDeque 代替 Stack 的原因有很多,因为 ArrayDeque 是一个以数组形式实现的双端队列。因此,它可以相对更快地增长。如果您不打算使用同步堆栈,那么 ArrayDeque 可能比堆栈更好,后者是线程安全的(因此很慢)。 ArrayDeque 也有更好的引用局部性。

      【讨论】:

        【解决方案5】:

        关键字是“可能”。如果确实发生了调整大小,那么它可能会变慢,但堆栈不太可能增长那么多。

        【讨论】:

          【解决方案6】:

          只要您执行的主要操作不是“包含”搜索或“批量插入”等,与其他数据结构相比,数组的工作速度会更快。 “更快”的部分始终取决于使用情况。平均而言,即平均时间,ArrayDeque 将比 Stack 快。

          【讨论】:

            猜你喜欢
            • 2015-06-17
            • 2015-07-11
            • 2018-08-04
            • 2016-09-20
            • 1970-01-01
            • 1970-01-01
            • 2014-09-05
            • 2019-12-07
            • 1970-01-01
            相关资源
            最近更新 更多