队列<T> vs List <T>

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

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

我会这样说: Queue<T>会更明确地暴露你的意图 ,人们知道一个队列是如何工作的。

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

如果这会给你带来可衡量的性能问题,你可以解决它。 不要预先解决所有潜在的性能问题。

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

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

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

也就是说, Stack<T> vs List<T>更接近,推送和popup操作没有性能差异。 他们都推动结束和从arrays结构(两者都是O(1))结束。


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

除了Queue<T>类实现队列和List<T>类实现列表之外,还有一个性能差异。

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

我想强调HugoRune已经指出的。 队列比列表快得多,在这个用例中,列表的内存访问是1对n。 我有一个类似的用例,但我有数百个值,我将使用队列,因为它是一个数量级更快。

关于在列表顶部实现的队列的说明:关键是“已实施”。 它不会在出队时将每个值复制到新的内存位置,而是使用循环缓冲区。 这可以在“列表顶部”完成,而不需要直接使用列表的副本的处罚。