protobuf.net を使用して大量のデータをデシリアライズしたいのですが、マルチスレッドではスループットを改善できないことがわかりました。
私のテストシナリオ:
- シングルスレッド、CPU 負荷は 25% (1/4 CPU リソース)
- シングルスレッド、4 プロセス、CPU 負荷は 9x % (4/4 CPU リソース)
- 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();
}
}
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);
ありがとう。