具有队列基​​本功能的最快 Java 集合是啥?

Posted

技术标签:

【中文标题】具有队列基​​本功能的最快 Java 集合是啥?【英文标题】:What is the fastest Java collection with the basic functionality of a Queue?具有队列基​​本功能的最快 Java 集合是什么? 【发布时间】:2011-09-02 01:20:13 【问题描述】:

Java 中最快的集合是什么?

我只需要添加和删除的操作,顺序不重要,equals元素不是问题,无非添加和删除很重要。

没有限制大小也很重要。

这些集合里面会有对象。

目前我正在使用 ArrayDeque,因为我看到这是更快的队列实现。

【问题讨论】:

如果顺序不重要,你就不用排队了。 目前我正在添加final并从头开始检索(如队列),但如果我可以一个一个取出所有元素,我可以使用另一个Collection。 "...过早的优化是万恶之源" 选择正确的集合并不是过早的优化。 BoltClock,这对于 Java 中的大写 Q 队列是不正确的。它仅表示“带有 head 元素的可变集合”。重读 java.util.Queue。 【参考方案1】:

您可以使用java.util.LinkedList - 它是双向链接和环形的,因此添加到一端并从另一端取出是 O(1)

无论您选择什么实现,请通过Queue 接口引用它,这样如果结果不适合您的情况,您可以轻松更改它(当然,如果您首先需要队列)

更新:Colin 的回答显示了一个基准,得出的结论是 ArrayDeque 更好。两者都有 O(1) 操作,但 LinkedList 创建新对象(节点),这会稍微影响性能。由于两者都有 O(1) 我认为选择 LinkedList 不会太错误。

【讨论】:

ArrayDeque 客观上更好。 @ColinD - 我看到了,但为什么呢?由于 linekdlist 中的对象创建(节点)?两者似乎都是 O(1) @ColinD @Bozho ArrayDeque 中的数组大小调整也是如此。这里真正的考虑是算法的复杂性。任何涉及数组的添加/删除都是 O(N),任何涉及链接的都是 O(1)。 @EJP: ArrayDeque is O(1) 用于在前端/端添加和删除(即用作队列或堆栈时),因为它是一个循环数组并且在这些情况下不会复制任何内容。此外,调整大小是一种偶尔的操作,通常可以通过适当的初始容量来避免。 LinkedList 的额外对象创建开销(加上该对象的垃圾收集)会影响队列上的每个添加/删除。我链接的基准显示它始终是 LinkedList 的 3 倍。 O(1) != O(1)O() 只是复杂性的衡量标准,而不是执行时间的衡量标准。无论n如何,一个总是需要5年的操作是O(1),一个总是需要5毫秒的操作也是如此。我宁愿使用需要 5 毫秒的那个。如果n 不会变得太大,即使是每个元素需要 5 毫秒的操作(即 O(n))也会比 5 年的操作要好。【参考方案2】:

ArrayDeque 是最好的。请参阅来自this blog post 的this benchmark,了解对此进行基准测试的结果。 ArrayDeque 没有LinkedList 没有的节点分配开销,也没有ArrayList 具有的移动数组内容的开销。在基准测试中,它对于大型队列的性能大约为 3x 以及 LinkedList,对于空队列甚至比 ArrayList 略好。为获得最佳性能,您可能希望为其提供足够大的初始容量以容纳一次可能容纳的元素数量,以避免多次调整大小。

ArrayListLinkedList 之间,似乎它取决于队列在任何给定时间将包含的平均总元素数,并且LinkedList 击败ArrayList 从大约10 个元素开始。

【讨论】:

ArrayList 用作栈应该和ArrayDeque一样,初始容量对性能影响很大。太多意味着要分配和收集更多的内存,太少意味着更多的副本(但对于紧密循环来说,总体而言比太大要好)。我看不到基准的来源,它可用吗? @bestsss:是的,用作堆栈ArrayList 将大致等效,尽管ArrayDeque 的javadoc 表明它可能会稍快一些。是的,考虑到问题中的要求,类似堆栈的使用会很好。不过,该基准测试专门用于 FIFO 队列(您可以在链接的博客文章中查看代码示例)。 我知道这个问题已经过时了,但是你的两个链接都已经失效了。是否有任何替代网址? 由于和@rath有同样的问题,我爬取了原博客,找到了原文:https://publicobject.com/2010/07/07/caliper_confirms_reality_linked_list_vs_array_list/。不幸的是,如果我尝试查看基准测试结果,我会收到 401 - 未经授权的错误。 这里还有另一个实验证实 ArrayDeque 比 LinkedList 快 3 倍:java-performance.info/linkedlist-performance【参考方案3】:

ConcurrentLinkedDeque 是多线程队列的最佳选择

【讨论】:

以上是关于具有队列基​​本功能的最快 Java 集合是啥?的主要内容,如果未能解决你的问题,请参考以下文章

大型数据集最快的分类算法是啥? [关闭]

MongoDB - 更新集合中所有记录的最快方法是啥?

确定一个值是不是在 Java 中的一组值中的最快方法是啥?

具有最快(并发)添加操作的集合

Java中的线程--并发库中的集合

为 UICollectionView 布局散列一个非常大的数据集的最快方法是啥... NSIndexPath 太慢了