通过多线程 protobuf.net

本文关键字:net protobuf 多线程 | 更新日期: 2023-09-27 18:35:14

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

我的测试场景:

  1. 单线程,CPU 负载为 25%(1/4 CPU 资源)
  2. 单线程,4 个进程,CPU 负载为 9x %(4/4 CPU 资源)
  3. 4个线程,1个进程,CPU负载为30%~60%

也就是说,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();
        }
    }

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

我用于测试并行的代码:

        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);

谢谢。

通过多线程 protobuf.net

我可以给你一个如何使用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 倍。而且处理器利用率也不同