title: .NET 4.0 Concurrent collection performance
body: <p>I am trying to write a program where i schedule items for removal by putting them in a collection from different threads and cleaning them up in a single thread that iterates of the collection and disposes the items.</p>
  
  <p>Before doing so, I wondered what would yield the optimal performance so I've tried ConcurrentBag, ConcurrentStack and ConcurrentQueue and measured the time required to add 10000000 items.</p>
  
  <p>I used the following program to test this:</p>
  
  <pre><code>class Program
  {
      static List&lt;int&gt; list = new List&lt;int&gt;();
      static ConcurrentBag&lt;int&gt; bag = new ConcurrentBag&lt;int&gt;();
      static ConcurrentStack&lt;int&gt; stack = new ConcurrentStack&lt;int&gt;();
      static ConcurrentQueue&lt;int&gt; queue = new ConcurrentQueue&lt;int&gt;();
      static void Main(string[] args)
      {
          run(addList);
          run(addBag);
          run(addStack);
          run(addQueue);
          Console.ReadLine();
      }
  
      private static void addList(int obj) { lock (list) { list.Add(obj); } }
  
      private static void addStack(int obj) { stack.Push(obj); }
  
      private static void addQueue(int obj) { queue.Enqueue(obj); }
  
      private static void addBag(int obj) { bag.Add(obj); }
  
  
  
      private static void run(Action&lt;int&gt; action)
      {
          Stopwatch stopwatch = Stopwatch.StartNew();
          Parallel.For(0, 10000000, new ParallelOptions() { MaxDegreeOfParallelism = # }, action);
          stopwatch.Stop();
          Console.WriteLine(action.Method.Name + " takes " + stopwatch.Elapsed);
      }
  }
  </code></pre>
  
  <p>where # is the amount of threads used.</p>
  
  <p>but the results are rather confusing:</p>
  
  <p>with 8 threads:</p>
  
  <ul>
  <li>addList takes 00:00:00.8166816</li>
  <li>addBag takes 00:00:01.0368712</li>
  <li>addStack takes 00:00:01.0902852</li>
  <li>addQueue takes 00:00:00.6555039</li>
  </ul>
  
  <p>with 1 thread:</p>
  
  <ul>
  <li>addList takes 00:00:00.3880958</li>
  <li>addBag takes 00:00:01.5850249</li>
  <li>addStack takes 00:00:01.2764924</li>
  <li>addQueue takes 00:00:00.4409501</li>
  </ul>
  
  <p>so, no matter how many threads, it seems that just locking a plain old list is faster then using any of the concurrent collections, except, perhaps the queue if it needs to handle a lot of writes.</p>
  
  <p>EDIT: after the comments below about Garbage and Debug build:
  Yes, this influences the benchmark. Debug build influence would be linear, Garbage would be increasing with higher memory usage.</p>
  
  <p>Yet running the same test multiple times gives roughly the same results.</p>
  
  <p>I moved the initialization of the collection to right before the test run and collect the garbage after the run now, like this:</p>
  
  <pre><code>        list = new List&lt;int&gt;();
          run(addList);
          list = null;
          GC.Collect();
  </code></pre>
  
  <p>with MaxDegreeOfParallelism set to 8 i get the following results:</p>
  
  <ul>
  <li>addList takes 00:00:7959546</li>
  <li>addBag takes 00:00:01.08023823</li>
  <li>addStack takes 00:00:01.1354566</li>
  <li>addQueue takes 00:00:00.6597145</li>
  </ul>
  
  <p>with give or take 0.02 seconds deviation each time i run the code.</p>