Goのシリアライゼーションのベンチマークを自分でも試してみた
2015年12月の記事ですが最速という噂のFlatbuffersの速度のヒミツと、導入方法の紹介(Go) - Qiitaを読んで、「gobは遅いのかー、残念」、「一方Flatbuffersは面倒そうだなー」と思っていました。
で、alecthomas/go_serialization_benchmarks at 48e2bb8b7b6c38c24c88a0b027b30c80175a7b59のベンチマーク結果を見てみると、あれgob遅くないよ、というかVmihailencoMsgpackとUgorjiCodecMsgpackより速くなってました。
自宅サーバ (NEC Express5800/S70)でもベンチマークを試してみました。
$ go test -bench . -benchmem | tee bench.txt
A test suite for benchmarking various Go serialization methods.
See README.md for details on running the benchmarks.
PASS
BenchmarkMsgpMarshal-2 3000000 423 ns/op 128 B/op 1 allocs/op
BenchmarkMsgpUnmarshal-2 2000000 741 ns/op 112 B/op 3 allocs/op
BenchmarkVmihailencoMsgpackMarshal-2 500000 3107 ns/op 368 B/op 6 allocs/op
BenchmarkVmihailencoMsgpackUnmarshal-2 300000 4469 ns/op 352 B/op 13 allocs/op
BenchmarkJsonMarshal-2 200000 7070 ns/op 1232 B/op 10 allocs/op
BenchmarkJsonUnmarshal-2 200000 7331 ns/op 416 B/op 7 allocs/op
BenchmarkEasyJsonMarshal-2 500000 3116 ns/op 784 B/op 5 allocs/op
BenchmarkEasyJsonUnmarshal-2 500000 2936 ns/op 160 B/op 4 allocs/op
BenchmarkBsonMarshal-2 500000 3031 ns/op 392 B/op 10 allocs/op
BenchmarkBsonUnmarshal-2 500000 4047 ns/op 248 B/op 21 allocs/op
BenchmarkGobMarshal-2 1000000 2189 ns/op 48 B/op 2 allocs/op
BenchmarkGobUnmarshal-2 1000000 2226 ns/op 112 B/op 3 allocs/op
BenchmarkXdrMarshal-2 500000 3862 ns/op 456 B/op 21 allocs/op
BenchmarkXdrUnmarshal-2 500000 2885 ns/op 239 B/op 11 allocs/op
BenchmarkUgorjiCodecMsgpackMarshal-2 200000 7052 ns/op 2752 B/op 8 allocs/op
BenchmarkUgorjiCodecMsgpackUnmarshal-2 200000 7586 ns/op 3008 B/op 6 allocs/op
BenchmarkUgorjiCodecBincMarshal-2 200000 7347 ns/op 2784 B/op 8 allocs/op
BenchmarkUgorjiCodecBincUnmarshal-2 200000 8163 ns/op 3168 B/op 9 allocs/op
BenchmarkSerealMarshal-2 200000 7518 ns/op 912 B/op 21 allocs/op
BenchmarkSerealUnmarshal-2 200000 7039 ns/op 1008 B/op 34 allocs/op
BenchmarkBinaryMarshal-2 500000 2757 ns/op 256 B/op 16 allocs/op
BenchmarkBinaryUnmarshal-2 500000 3057 ns/op 336 B/op 22 allocs/op
BenchmarkFlatBuffersMarshal-2 3000000 573 ns/op 0 B/op 0 allocs/op
BenchmarkFlatBuffersUnmarshal-2 3000000 538 ns/op 112 B/op 3 allocs/op
BenchmarkCapNProtoMarshal-2 2000000 874 ns/op 56 B/op 2 allocs/op
BenchmarkCapNProtoUnmarshal-2 2000000 817 ns/op 200 B/op 6 allocs/op
BenchmarkCapNProto2Marshal-2 1000000 1991 ns/op 244 B/op 3 allocs/op
BenchmarkCapNProto2Unmarshal-2 1000000 2064 ns/op 320 B/op 6 allocs/op
BenchmarkHproseMarshal-2 1000000 1797 ns/op 479 B/op 8 allocs/op
BenchmarkHproseUnmarshal-2 500000 2250 ns/op 320 B/op 10 allocs/op
BenchmarkProtobufMarshal-2 1000000 2052 ns/op 200 B/op 7 allocs/op
BenchmarkProtobufUnmarshal-2 1000000 1700 ns/op 192 B/op 10 allocs/op
BenchmarkGoprotobufMarshal-2 1000000 1141 ns/op 312 B/op 4 allocs/op
BenchmarkGoprotobufUnmarshal-2 1000000 1721 ns/op 432 B/op 9 allocs/op
BenchmarkGogoprotobufMarshal-2 5000000 291 ns/op 64 B/op 1 allocs/op
BenchmarkGogoprotobufUnmarshal-2 3000000 445 ns/op 96 B/op 3 allocs/op
BenchmarkColferMarshal-2 5000000 260 ns/op 64 B/op 1 allocs/op
BenchmarkColferUnmarshal-2 5000000 387 ns/op 112 B/op 3 allocs/op
BenchmarkGencodeMarshal-2 5000000 322 ns/op 80 B/op 2 allocs/op
BenchmarkGencodeUnmarshal-2 5000000 392 ns/op 112 B/op 3 allocs/op
BenchmarkGencodeUnsafeMarshal-2 10000000 196 ns/op 48 B/op 1 allocs/op
BenchmarkGencodeUnsafeUnmarshal-2 5000000 322 ns/op 96 B/op 3 allocs/op
BenchmarkXDR2Marshal-2 5000000 333 ns/op 64 B/op 1 allocs/op
BenchmarkXDR2Unmarshal-2 5000000 313 ns/op 32 B/op 2 allocs/op
ok github.com/alecthomas/go_serialization_benchmarks 81.009s
$ go version
go version go1.6.2 linux/amd64
こちらも同じくgobはVmihailencoMsgpackとUgorjiCodecMsgpackより速かったです。Goのバージョンの違いなのかライブラリの進化なのかは調べてないですが、いつのまにか逆転していたようです。
ということで、Go以外の言語との相互運用性を考えなくて良いなら、gobもシリアライゼーションのライブラリ選択の候補に入れて良さそうと思いました。gobを見る限りはstructに対して特に何もしなくても使えるようなのでお手軽さでは一番良さそうですし。