title: protobuf.net via multi-threading
body: <p>I want to deserialize lots of data using protobuf.net, but I found it cannot improve throughput via multi-threading. </p>
  
  <p>my testing scenario:</p>
  
  <ol>
  <li>single-thread, CPU load is 25% (1/4 cpu resource)</li>
  <li>single-thread, 4 processes, cpu load is 9x % (4/4 cpu resource)</li>
  <li>4 threads, 1 process, cpu load is 30% ~ 60% </li>
  </ol>
  
  <p>that's, protobuf cannot fully utilize cpu resource under multi-threading.</p>
  
  <h2>Here is my code</h2>
  
  <pre><code>    private static void DeSerialize()
      {
          while (true)
          { 
              Dictionary&lt;string, byte[]&gt;  cache ;
              if (queue.TryDequeue(out cache))
              {
                  foreach (byte[] unit in cache.Values)
                  {
                      using (MemoryStream stream = new MemoryStream(unit))
                      {
                          CommonUtil.DeSerializeBuf&lt;User&gt;(stream);
                      }
                  }
              }
              else break;
          }
      }
  
      private static void DeSerializeThread()
      {
          for (int i = 0; i &lt; 4; i++)
          {
              Thread a = new Thread(DeSerialize);
              a.Start();
          }
      }
  </code></pre>
  
  <p>How can protobuf.net fully utilize multiple CPU resources via multi-threading? multi-process is not acceptable in my case.</p>
  
  <p>my code for testing the Parallel:</p>
  
  <pre><code>        var dic = new Dictionary&lt;string, byte[]&gt;();
          for (int i = 0; i &lt; 10000000; i++)
          {
              MemoryStream stream = new MemoryStream();
              ProtoBuf.Serializer.Serialize&lt;string&gt;(stream, "some value which is awesome" + i);
              byte[] buffer = stream.ToArray();
              dic.Add("key" + i, buffer);
          }
  
          var watch = new Stopwatch();
          watch.Restart();
          Console.Write("start parallel..");
  
          var result = dic.AsParallel().Select(p =&gt; ProtoBuf.Serializer.Deserialize&lt;string&gt;(new MemoryStream(p.Value))).ToList();
          var p1 = watch.ElapsedMilliseconds;
          Console.WriteLine("end parallel " + p1);
  
          watch.Restart();
          Console.Write("start sequential..");
  
          var result2 = dic.Select(p =&gt; CommonUtil.DeSerializeBuf&lt;string&gt;(new MemoryStream(p.Value))).ToList();
          var p2 = watch.ElapsedMilliseconds;
          Console.WriteLine("end parallel " + p2);
  </code></pre>
  
  <p>thanks.</p>