I'm currently using a List<T>
as a queue (use lst[0]
then lst.removeAt(0)
) to hold objects. There's about 20 items max at a given time. I realized there was an actual Queue<T>
class. I'm wondering if there's any benefit (performance, memory, etc.) to using a Queue<T>
over a List<T>
acting like a queue?
相关问题
- Generic Generics in Managed C++
- how to split a list into a given number of sub-lis
- How to Debug/Register a Permanent WMI Event Which
- 'System.Threading.ThreadAbortException' in
- Faster loop: foreach vs some (performance of jsper
I wanted to emphasize what HugoRune already pointed out.
Queue
is significantly faster thanList
, where memory accesses are1
vs.n
forList
in this use case. I have a similar use case but I have hundreds of values and I will useQueue
because it is an order of magnitude faster.A note about
Queue
being implemented on top ofList
: the key word is "implemented". It doesn't copy every value to a new memory location upon dequeue, rather using a circular buffer. This can be done on "top ofList
" without the penalties of copies that direct usage ofList
implies.Short answer:
Queue<T>
is faster thanList<T>
when it's used like a queue.List<T>
is faster thanQueue<T>
when used like a list.Long answer:
A
Queue<T>
is faster for dequeuing operation, which is an O(1) operation. The entire block of subsequent items of the array is not moved up. This is possible because aQueue<T>
need not facilitate removal from random positions, but only from the top. So it maintains a head (from which the item is pulled uponDequeue
) and tail position (to which the item is added uponEnqueue
). On the other hand removing from the top of aList<T>
requires itself to shift positions of every subsequent item one up. This is O(n) - worst case if you're removing from the top, which is what a dequeue operation is. The speed advantage can be noticeable if you're dequeuing in a loop.A
List<T>
is more performant if you need indexed access, random retrieval etc. AQueue<T>
will have to enumerate fully to find the appropriate index position (it doesn't exposeIList<T>
).That said, a
Stack<T>
vsList<T>
is much closer, there is no performance difference in pushing and popping operations. They both push to end and remove from end of array structures (both of which are O(1)).Of course you should use the correct structure that reveals the intent. In most cases they will perform better as well since they are tailor-made for the purpose. I believe had there been no performance difference at all, Microsoft wouldn't have included
Queue<T>
andStack<T>
in the framework for merely different semantics. It would have been simply easily extensible if that was the case. Think aboutSortedDictionary<K, V>
andSortedList<K, V>
, both of which do exactly the same but is differentiated by only performance characteristic; they find a place in BCL.Performance can be profiled. Though in this case of so few items, you may need to run the code millions of times to actually get worthwhile differences.
I will say this:
Queue<T>
will expose your intent more explicitly, people know how a queue works.A list being used like a queue is not as clear, especially if you have a lot of needless indexing and
RemoveAt(magicNumber)
code.Dequeue
is a lot more consumable from a code maintenance point of view.If this then gives you measurable performance issues, you can address it. Don't address every potential performance issue upfront.
Besides the fact that the
Queue<T>
class implements a queue and theList<T>
class implement a list there is a performance difference.Every time you remove the first element from
List<T>
all elements in the queue are copied. With only 20 elements in the queue it may not be noticeable. However, when you dequeue the next element fromQueue<T>
no such copying is happening and that will always be faster. If the queue is long the difference can be significant.