title: How to speed up routines making use of collections in multithreading scenario
body: <p>I've an application that makes use of parallelization for processing data.</p>
  
  <p>The main program is in C#, while one of the routine for analyzing data is on an external C++ dll. This library scans data and calls a callback everytime a certain signal is found within the data. Data should be collected, sorted and then stored into HD.</p>
  
  <p>Here is my first simple implementation of the method invoked by the callback and of the method for sorting and storing data:</p>
  
  <pre><code>// collection where saving found signals
  List&lt;MySignal&gt; mySignalList = new List&lt;MySignal&gt;();
  
  // method invoked by the callback
  private void Collect(int type, long time)
  {
      lock(locker) { mySignalList.Add(new MySignal(type, time)); }
  }
  
  // store signals to disk
  private void Store()
  {
      // sort the signals
      mySignalList.Sort();
      // file is a object that manages the writing of data to a FileStream
      file.Write(mySignalList.ToArray());
  }
  </code></pre>
  
  <p>Data is made up of a bidimensional array (short[][] data) of size 10000 x n, with n variable. I use parallelization in this way:</p>
  
  <pre><code>Parallel.For(0, 10000, (int i) =&gt;
  {
      // wrapper for the external c++ dll
      ProcessData(data[i]);
  }
  </code></pre>
  
  <p>Now for each of the 10000 arrays I estimate that 0 to 4 callbacks could be fired. I'm facing a bottleneck and given that my CPU resources are not over-utilized, I suppose that  the lock (together with thousand of callbacks) is the problem (am I right or there could be something else?). I've tried the ConcurrentBag collection but performances are still worse (in line with other user <a href="https://stackoverflow.com/questions/4785622/why-is-concurrentbagt-so-slow-in-net-4-0-am-i-doing-it-wrong">findings</a>).</p>
  
  <p>I thought that a possible solution for use lock-free code would be to have multiple collections. Then it would be necessary a strategy to make each thread of the parallel process working on a single collection. Collections could be for instance inside a dictionary with thread ID as key, but I do not know any .NET facility for this (I should know the threads ID for initialize the dictionary before launching the parallelization). Could be this idea feasible and, in case yes, does exist some .NET tool for this? Or alternatively, any other idea to speed up the process?</p>
  
  <p>[EDIT]
  I've followed the Reed Copsey's suggestion and I used the following solution (according to the profiler of VS2010, before the burden for locking and adding to the list was taking 15% of the resources, while now only 1%):</p>
  
  <pre><code>// master collection where saving found signals
  List&lt;MySignal&gt; mySignalList = new List&lt;MySignal&gt;();
  // thread-local storage of data (each thread is working on its List&lt;MySignal&gt;)
  ThreadLocal&lt;List&lt;MySignal&gt;&gt; threadLocal;
  
  // analyze data
  private void AnalizeData()
  {
      using(threadLocal = new ThreadLocal&lt;List&lt;MySignal&gt;&gt;(() =&gt; 
          { return new List&lt;MySignal&gt;(); }))
      {
          Parallel.For&lt;int&gt;(0, 10000,
          () =&gt;
          { return 0;},
          (i, loopState, localState) =&gt;
          {
              // wrapper for the external c++ dll
              ProcessData(data[i]);
              return 0;
          },
          (localState) =&gt;
          {
              lock(this)
              {
                  // add thread-local lists to the master collection
                  mySignalList.AddRange(local.Value);
                  local.Value.Clear();
              }
          });
      }
  }
  
  // method invoked by the callback
  private void Collect(int type, long time)
  {
      local.Value.Add(new MySignal(type, time));
  }
  </code></pre>