🧊
C# バイナリ/JSONシリアライザ選択
要点
ベンチマーク
Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
---|---|---|---|---|---|---|
MemoryPack | 91.80 ns | 0.143 ns | 0.120 ns | 0.0229 | - | 144 B |
MessagePack | 125.93 ns | 0.249 ns | 0.233 ns | 0.0215 | - | 136 B |
DotnetJsonSerialize | 275.47 ns | 0.644 ns | 0.602 ns | 0.0267 | - | 168 B |
NewtonJsonSerialize | 565.93 ns | 1.130 ns | 1.001 ns | 0.6514 | 0.0038 | 4088 B |
Utf8JsonSerialize | 140.31 ns | 0.210 ns | 0.197 ns | 0.0343 | - | 216 B |
MessagePackJsonSerialize | 702.00 ns | 0.772 ns | 0.722 ns | 0.1526 | - | 960 B |
結論としてはJSONだけで良いのであればSystem.Text.Jsonで良さそうです。結果だけ見るとUtf8Jsonが優秀なのですがリポジトリがアーカイブ状態なので採用は厳しそうです。
MessagePackJsonSerialize
はMessagePackのJSON出力機能のベンチマークです。JSONシリアライザのベンチマークを作ってた時、MessagePackにもJSON変換機能が入っていたので、一応項目に加えてみました。
MessagePackでJSONを出力するには一旦byte[]に変換しないといけないのでその手間が結果に響いています。なので「今MessagePackを使っているけど、その中の一部データをJSONにしたい」など、すでにMessagePackを採用しているのであれば良い選択だと思いますが、逆にJSONだけしか使う予定がないのであれば、わざわざMessagePackのJSON変換を使う必要は無さそうです。
ていうか
Utf8Json凄いですね・・・復活願ってます。
ベンチマークコード
[MemoryPackable]
[MessagePackObject]
public partial class Person
{
[Key(nameof(Age))]
public int Age { get; set; }
[Key(nameof(Name))]
public string Name { get; set; }
}
[MemoryDiagnoser]
public class BinarySerializerBench
{
[Benchmark]
public Person MemoryPack()
{
var v = new Person { Age = 40, Name = "John" };
var bin = MemoryPackSerializer.Serialize(v);
var val = MemoryPackSerializer.Deserialize<Person>(bin);
return val;
}
[Benchmark]
public Person MessagePack()
{
var v = new Person { Age = 40, Name = "John" };
var bin = MessagePackSerializer.Serialize(v);
var val = MessagePackSerializer.Deserialize<Person>(bin);
return val;
}
[Benchmark]
public Person DotnetJsonSerialize()
{
var v = new Person { Age = 40, Name = "John" };
var bin = System.Text.Json.JsonSerializer.Serialize(v);
var val = System.Text.Json.JsonSerializer.Deserialize<Person>(bin);
return val;
}
[Benchmark]
public Person NewtonJsonSerialize()
{
var v = new Person { Age = 40, Name = "John" };
var bin = JsonConvert.SerializeObject(v);
var val = JsonConvert.DeserializeObject<Person>(bin);
return val;
}
[Benchmark]
public Person Utf8JsonSerialize()
{
var v = new Person { Age = 40, Name = "John" };
var bin = Utf8Json.JsonSerializer.ToJsonString(v);
var val = Utf8Json.JsonSerializer.Deserialize<Person>(bin);
return val;
}
[Benchmark]
public Person MessagePackJsonSerialize()
{
var v = new Person { Age = 40, Name = "John" };
var bin = MessagePackSerializer.Serialize(v);
var json = MessagePackSerializer.ConvertToJson(bin);
var res = MessagePackSerializer.ConvertFromJson(json);
var val = MessagePackSerializer.Deserialize<Person>(res);
return val;
}
}
リンク
Discussion