Is ConcurrentBag(T) optimized for single-threaded scenarios? If so, why concurrent?
The MSDN documentation on the ConcurrentBag<T>
class from .NET 4.0's concurrent collections library says this:
ConcurrentBag is a thread-safe bag implementation, optimized for scenarios where the same thread will be both producing and consuming data stored in the bag. [emphasis mine]
Am I missing something, or is this saying that the ConcurrentBag<T>
class is optimized for single-threaded scenarios?
If I'm not missing something... why would this be? It just seems pretty strange to have a开发者_开发知识库 collection designed for concurrency but optimized for one thread.
The optimization means that, if you have multiple threads both producing and consuming, there are optimizations in place such that it's fastest if it can return an item that was placed in the bag by the same thread.
Where this optimization doesn't apply is if a thread asks the bag for an item, and there are no more items left in the bag that were placed there by that thread. In that case, it can still retrieve an item from the bag (placed in there by another thread), but it's less optimal.
Or, to put it another way: It's Concurrent because multiple threads can be producing into it and consuming from it simultaneously, without external locking. The mentioned optimization doesn't make this untrue.
Three scenarios where you might use a ConcurrentBag
and how this optimization affects them:
1) Separate producer and consumer threads. No effect.
2) Threads that are both consumers and producers storing and retrieving data from the ConcurrentBag
. The optimization will improve performance for same-thread add / retrieve operations.
3) Single threaded scenarios that could use a regular collection. The optimization means that there is little overhead in using a ConcurrentBag
so you can use it without a huge performance hit.
What the documentation tries to say is that it prefers the same thread producing and consuming data.
It has a fast path where when the same thread produces and consumes data, the data stays on that thread (think [ThreadStatic]
). However, when there is no data to consume on the same thread, it goes looking on other threads and gets data from there.
Look e.g. at http://www.codethinked.com/post/2010/01/27/NET-40-and-System_Collections_Concurrent_ConcurrentBag.aspx for a more detailed explanation of this.
精彩评论