队列<T>与列表<T>

Jac*_*ack 45 .net queue performance list difference

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

Ada*_*rth 71

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

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

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

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

  • @JohnIsaiahCarmona:因为在10个元素上使用O(n ^ 2)算法而不是O(n)算法不是性能问题. (22认同)
  • @JohnIsaiahCarmona因为当你不需要时,你会陷入微优化的陷阱.我对这一切的看法是我们应该注意明显的支撑,但A和B之间的几毫秒不值得担心,直到它们成为一个问题.在大多数情况下,可维护,可读的代码比性能更重要. (17认同)
  • 为什么我们不应该提前解决所有潜在的性能问题? (7认同)
  • @JohnIsaiahCarmona此外,大多数潜在的性能问题从未真正实现,因此它们只是*潜在的*问题. (6认同)
  • 好,可以. (4认同)
  • 我们不要完全忽视@JohnIsaiahCarmona。我们应该始终鼓励开发人员了解这些东西是如何在幕后实现的。更实际的是,我们都知道这些故事是如何进行制作的——有些将一些“临时”的东西放在一起,快进 5 年,但它仍在交付,现在其他一些组件正在以性能损失相互调节的方式对其进行打击。这可能不太适合这个问题,但我认识的最好的开发人员都在努力了解如何对他们的代码进行打击/压力。 (4认同)

naw*_*fal 40

简短的回答:
Queue<T>List<T>像队列一样使用它的速度要快.List<T>Queue<T>列表使用时更快.

答案长:
A 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找到了一席之地.

  • @AlexanderRyanBaggett 它应该没有什么区别(我最好的猜测),但你真的应该使用更好地揭示意图的结构。他们都向开发人员讲述了不同的故事。 (2认同)

Mar*_*age 11

除了Queue<T>类实现队列并且List<T>类实现列表这一事实之外还存在性能差异.

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