队列<t>与列表<t> </t> </t>

时间:2012-04-30 08:35:38

标签: .net performance list queue difference

我目前正在使用List<T>作为队列(使用lst[0]然后lst.removeAt(0))来保存对象。在给定时间最多约20项。我意识到有一个实际的Queue<T>课程。我想知道在Queue<T>上使用List<T>作为队列是否有任何好处(性能,内存等)?

4 个答案:

答案 0 :(得分:69)

可以分析性能。虽然在这种情况下项目很少,但您可能需要运行代码数百万次才能真正获得有价值的差异。

我会这样说:Queue<T>会更明确地公开您的 意图 ,人们知道队列是如何运作的。

像队列一样使用的列表不是很清楚,特别是如果你有很多不必要的索引和RemoveAt(magicNumber)代码。从代码维护的角度来看,Dequeue更具消费性。

如果这会给您带来可衡量的性能问题,您可以解决它。不要提前解决每个潜在的性能问题。

答案 1 :(得分:37)

简答:
当它像队列一样被使用时,Queue<T>List<T>快。像列表一样使用List<T>Queue<T>快。

答案很长:
对于出列操作,Queue<T>更快,这是一个O(1)操作。数组的后续项的整个块不会向上移动。这是可能的,因为Queue<T>不需要便于从随机位置移除,而只能从顶部移除。因此它保持一个头部(项目从Dequeue上拉)和尾部位置(项目在Enqueue上添加)。另一方面,从List<T>的顶部移除需要自己将每个后续项目的位置向上移动一个。这是O(n) - 最糟糕的情况,如果你从顶部移除,这是一个出队操作。如果您在循环中出列,速度优势可能会很明显。

如果您需要索引访问,随机检索等,List<T>会更高效。Queue<T>必须完全枚举才能找到合适的索引位置(它不会公开IList<T> )。

也就是说,Stack<T> vs List<T>更接近,推送和弹出操作没有性能差异。它们都推动结束并从阵列结构的末端移除(两者都是O(1))。


当然你应该使用揭示意图的正确结构。在大多数情况下,它们也会表现得更好,因为它们是为此目的而量身定做的。我相信,如果没有任何性能差异,微软就不会在框架中包含Queue<T>Stack<T>仅用于不同的语义。如果是这样的话,那将简单易于扩展。考虑SortedDictionary<K, V>SortedList<K, V>,两者都完全相同,但仅通过性能特征来区分;他们在BCL找到了一席之地。

答案 2 :(得分:11)

除了Queue<T>类实现队列而List<T>类实现列表这一事实外,还存在性能差异。

每次从List<T>中删除第一个元素时,都会复制队列中的所有元素。队列中只有20个元素,可能不会引人注意。但是,当您从Queue<T>出列下一个元素时,不会发生此类复制,并且总是会更快。如果队列很长,差异可能很大。

答案 3 :(得分:0)

我想强调HugoRune已经指出的内容。 Queue明显快于List,在此用例中,1的内存访问次数为nList的{​​{1}}。我有一个类似的用例,但我有数百个值,我将使用Queue因为它快一个数量级。

关于在Queue之上实施List的说明:关键字是“已实施”。它在出列时不会将每个值复制到新的内存位置,而是使用循环缓冲区。这可以在“List的顶部”完成,而不会直接使用List暗示的副本。