protobuf.net通过多线程

时间:2013-10-12 07:31:47

标签: c# multithreading protocol-buffers

我想使用protobuf.net对大量数据进行反序列化,但我发现它无法通过多线程提高吞吐量。

我的测试场景:

  1. 单线程,CPU负载为25%(1/4 cpu资源)
  2. 单线程,4个进程,cpu负载为9x%(4/4 cpu资源)
  3. 4个线程,1个进程,cpu负载为30%~60%
  4. 那就是,protobuf无法在多线程下充分利用cpu资源。

    这是我的代码

        private static void DeSerialize()
        {
            while (true)
            { 
                Dictionary<string, byte[]>  cache ;
                if (queue.TryDequeue(out cache))
                {
                    foreach (byte[] unit in cache.Values)
                    {
                        using (MemoryStream stream = new MemoryStream(unit))
                        {
                            CommonUtil.DeSerializeBuf<User>(stream);
                        }
                    }
                }
                else break;
            }
        }
    
        private static void DeSerializeThread()
        {
            for (int i = 0; i < 4; i++)
            {
                Thread a = new Thread(DeSerialize);
                a.Start();
            }
        }
    

    protobuf.net如何通过多线程充分利用多个CPU资源?在我的情况下,多流程是不可接受的。

    我测试Parallel的代码:

            var dic = new Dictionary<string, byte[]>();
            for (int i = 0; i < 10000000; i++)
            {
                MemoryStream stream = new MemoryStream();
                ProtoBuf.Serializer.Serialize<string>(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 => ProtoBuf.Serializer.Deserialize<string>(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 => CommonUtil.DeSerializeBuf<string>(new MemoryStream(p.Value))).ToList();
            var p2 = watch.ElapsedMilliseconds;
            Console.WriteLine("end parallel " + p2);
    

    感谢。

1 个答案:

答案 0 :(得分:0)

我可以给你一个简短的例子,说明如何使用Linq As parallel,也许这有帮助

var dic = new Dictionary<string, byte[]>();
for (int i = 0; i < 1000000; i++)
{
    dic.Add("key" + i, Serialize<string>("some value which is awesome" + i));
}

var watch = new Stopwatch();
watch.Restart();
Console.WriteLine("start parallel");

var result = dic.AsParallel().Select(p => Deserialize<string>(p.Value)).ToList();
var p1 = watch.ElapsedMilliseconds;

watch.Restart();
Console.WriteLine("start sequential");

var result2 = dic.Select(p => Deserialize<string>(p.Value)).ToList();
var p2 = watch.ElapsedMilliseconds;

在我的机器上并行执行时,差异大约快3倍。处理器利用率 不同