Before I started a project, I wrote a simple test to compare the performance of ConcurrentBag from (System.Collections.Concurrent) relative to locking & lists. I am extr
Looking at the program using MS's contention visualizer shows that ConcurrentBag
has a much higher cost associated with parallel insertion than simply locking on a List
. One thing I noticed is there appears to be a cost associated with spinning up the 6 threads (used on my machine) to begin the first ConcurrentBag
run (cold run). 5 or 6 threads are then used with the List
code, which is faster (warm run). Adding another ConcurrentBag
run after the list shows it takes less time than the first (warm run).
From what I'm seeing in the contention, a lot of time is spent in the ConcurrentBag
implementation allocating memory. Removing the explicit allocation of size from the List
code slows it down, but not enough to make a difference.
EDIT: it appears to be that the ConcurrentBag
internally keeps a list per Thread.CurrentThread
, locks 2-4 times depending on if it is running on a new thread, and performs at least one Interlocked.Exchange
. As noted in MSDN: "optimized for scenarios where the same thread will be both producing and consuming data stored in the bag." This is the most likely explanation for your performance decrease versus a raw list.