队列<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。 我有一个类似的用例,但我有数百个值,我将使用队列,因为它是一个数量级更快。
关于在列表顶部实现的队列的说明:关键是“已实施”。 它不会在出队时将每个值复制到新的内存位置,而是使用循环缓冲区。 这可以在“列表顶部”完成,而不需要直接使用列表的副本的处罚。