Home

Awesome

Benchmarks of Go serialization methods

Gitter chat

This is a test suite for benchmarking various Go serialization methods.

Tested serialization methods

Running the benchmarks

go get -u -t
go test -bench='.*' ./

To update the table in the README:

./stats.sh

Recommendation

If performance, correctness and interoperability are the most important factors, gogoprotobuf is currently the best choice. It does require a pre-processing step (eg. via Go 1.4's "go generate" command).

But as always, make your own choice based on your requirements.

Data

The data being serialized is the following structure with randomly generated values:

type A struct {
    Name     string
    BirthDay time.Time
    Phone    string
    Siblings int
    Spouse   bool
    Money    float64
}

Results

Results with Go 1.20 linux/amd64 on an Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz

benchmarkitertime/iterbytes/opallocs/optt.sectt.kbns/alloc
Benchmark_Gotiny_Marshal-83289964314 ns/op481681.03157911.87
Benchmark_Gotiny_Unmarshal-85535879203 ns/op481121.12265721.81
Benchmark_GotinyNoTime_Marshal-83071874356 ns/op481681.09147442.12
Benchmark_GotinyNoTime_Unmarshal-85650100196 ns/op47961.11271142.05
Benchmark_Msgp_Marshal-88620024129 ns/op971281.12836141.01
Benchmark_Msgp_Unmarshal-85248064225 ns/op971121.18509062.01
Benchmark_VmihailencoMsgpack_Marshal-81663527641 ns/op922641.07153042.43
Benchmark_VmihailencoMsgpack_Unmarshal-81256986940 ns/op921601.18115645.88
Benchmark_Json_Marshal-810000001031 ns/op1512081.03151604.96
Benchmark_Json_Unmarshal-84884342374 ns/op1513511.1674096.76
Benchmark_JsonIter_Marshal-81681933830 ns/op1412001.40237654.15
Benchmark_JsonIter_Unmarshal-810000001140 ns/op1412161.14141305.28
Benchmark_EasyJson_Marshal-89413301069 ns/op1518961.01142701.19
Benchmark_EasyJson_Unmarshal-810000001002 ns/op1511121.00151608.95
Benchmark_Bson_Marshal-812475241046 ns/op1103761.30137222.78
Benchmark_Bson_Unmarshal-86488961609 ns/op1102241.0471377.18
Benchmark_MongoBson_Marshal-87766591541 ns/op1102401.2085436.42
Benchmark_MongoBson_Unmarshal-87110961671 ns/op1104081.1978224.10
Benchmark_Gob_Marshal-82490104790 ns/op16316161.1940732.96
Benchmark_Gob_Unmarshal-84543330266 ns/op16377681.387433.90
Benchmark_XDR_Marshal-88110701409 ns/op924401.1474613.20
Benchmark_XDR_Unmarshal-810412311134 ns/op912311.1895784.91
Benchmark_UgorjiCodecMsgpack_Marshal-81297413946 ns/op9112401.23118060.76
Benchmark_UgorjiCodecMsgpack_Unmarshal-810902501072 ns/op916881.1799211.56
Benchmark_UgorjiCodecBinc_Marshal-810000001075 ns/op9512561.0795000.86
Benchmark_UgorjiCodecBinc_Unmarshal-88256021225 ns/op958481.0178431.44
Benchmark_Sereal_Marshal-85016242348 ns/op1328321.1866212.82
Benchmark_Sereal_Unmarshal-83575802838 ns/op1329761.0147202.91
Benchmark_Binary_Marshal-86028241684 ns/op613601.0236774.68
Benchmark_Binary_Unmarshal-88547931379 ns/op613201.1852144.31
Benchmark_FlatBuffers_Marshal-81201532913 ns/op953761.10114452.43
Benchmark_FlatBuffers_Unmarshal-84790798246 ns/op951121.18455552.20
Benchmark_CapNProto_Marshal-85911261883 ns/op9643921.1156740.43
Benchmark_CapNProto_Unmarshal-82406106471 ns/op961921.13230982.46
Benchmark_CapNProto2_Marshal-89152881132 ns/op9614521.0487860.78
Benchmark_CapNProto2_Unmarshal-82153727501 ns/op962721.08206751.84
Benchmark_Hprose_Marshal-810000001063 ns/op854121.0685252.58
Benchmark_Hprose_Unmarshal-811152001041 ns/op853041.1695073.42
Benchmark_Hprose2_Marshal-82596594436 ns/op8501.13221510.00
Benchmark_Hprose2_Unmarshal-82252002526 ns/op851361.18191963.87
Benchmark_Protobuf_Marshal-81770528665 ns/op521441.1892064.62
Benchmark_Protobuf_Unmarshal-81337763867 ns/op521841.1669564.71
Benchmark_Gogoprotobuf_Marshal-89092077126 ns/op53641.15481881.98
Benchmark_Gogoprotobuf_Unmarshal-85161258222 ns/op53961.15273542.31
Benchmark_Gogojsonpb_Marshal-810477410614 ns/op12631111.1113213.41
Benchmark_Gogojsonpb_Unmarshal-88502013541 ns/op12633831.1510724.00
Benchmark_Colfer_Marshal-89224456121 ns/op51641.12471001.90
Benchmark_Colfer_Unmarshal-86255799185 ns/op521121.16325301.66
Benchmark_Gencode_Marshal-87347620154 ns/op53801.13389421.93
Benchmark_Gencode_Unmarshal-86154107183 ns/op531121.13326161.63
Benchmark_GencodeUnsafe_Marshal-81161332194 ns/op46481.10534211.97
Benchmark_GencodeUnsafe_Unmarshal-87445767153 ns/op46961.14342501.60
Benchmark_XDR2_Marshal-87233091152 ns/op60641.10433982.39
Benchmark_XDR2_Unmarshal-89237249118 ns/op60321.09554233.70
Benchmark_GoAvro_Marshal-84504522340 ns/op477281.0521173.21
Benchmark_GoAvro_Unmarshal-81995645578 ns/op4725441.119372.19
Benchmark_GoAvro2Text_Marshal-83619722971 ns/op13313201.0848432.25
Benchmark_GoAvro2Text_Unmarshal-83934512777 ns/op1337361.0952643.77
Benchmark_GoAvro2Binary_Marshal-81401618848 ns/op474641.1965871.83
Benchmark_GoAvro2Binary_Unmarshal-81282917941 ns/op475441.2160291.73
Benchmark_Ikea_Marshal-812215381160 ns/op551841.4267186.30
Benchmark_Ikea_Unmarshal-81458270929 ns/op551601.3680205.81
Benchmark_ShamatonMapMsgpack_Marshal-81667377700 ns/op921921.17153393.65
Benchmark_ShamatonMapMsgpack_Unmarshal-81787547733 ns/op921681.31164454.37
Benchmark_ShamatonArrayMsgpack_Marshal-81944530620 ns/op501601.2197223.88
Benchmark_ShamatonArrayMsgpack_Unmarshal-82137424557 ns/op501681.19106873.32
Benchmark_ShamatonMapMsgpackgen_Marshal-85579025210 ns/op92961.17513272.19
Benchmark_ShamatonMapMsgpackgen_Unmarshal-83038484393 ns/op921121.19279543.51
Benchmark_ShamatonArrayMsgpackgen_Marshal-87379319157 ns/op50641.16368962.46
Benchmark_ShamatonArrayMsgpackgen_Unmarshal-85105184289 ns/op501121.48255252.58
Benchmark_SSZNoTimeNoStringNoFloatA_Marshal-81909305616 ns/op554401.07105012.76
Benchmark_SSZNoTimeNoStringNoFloatA_Unmarshal-81442567495 ns/op5511841.087936.33
Benchmark_Bebop_Marshal-88837412130 ns/op55641.16486052.05
Benchmark_Bebop_Unmarshal-810519754113 ns/op55321.20578583.55
Benchmark_FastJson_Marshal-81391612771 ns/op1335041.07186191.53
Benchmark_FastJson_Unmarshal-86160301898 ns/op13317041.1782421.11
Benchmark_Musgo_Marshal-89924801108 ns/op46481.08456542.26
Benchmark_Musgo_Unmarshal-86210996182 ns/op46961.13285701.90
Benchmark_MusgoUnsafe_Marshal-811188216100 ns/op46481.13514652.10
Benchmark_MusgoUnsafe_Unmarshal-89953605112 ns/op46641.12457861.76

Totals:

benchmarkitertime/iterbytes/opallocs/optt.sectt.kbns/alloc
Benchmark_MusgoUnsafe_-821141821213 ns/op921124.511945041.91
Benchmark_Bebop_-819357166244 ns/op110964.732129282.55
Benchmark_GencodeUnsafe_-819059088248 ns/op921444.731753431.72
Benchmark_XDR2_-816470340271 ns/op120964.461976442.82
Benchmark_Musgo_-816135797290 ns/op921444.691484492.02
Benchmark_Colfer_-815480255307 ns/op1031764.761595391.75
Benchmark_Gencode_-813501727337 ns/op1061924.551431181.76
Benchmark_Gogoprotobuf_-814253335349 ns/op1061604.981510852.18
Benchmark_Msgp_-813868088355 ns/op1942404.922690401.48
Benchmark_ShamatonArrayMsgpackgen_-812484503447 ns/op1001765.581248452.54
Benchmark_Gotiny_-88825843517 ns/op962804.57847281.85
Benchmark_GotinyNoTime_-88721974553 ns/op952644.82837222.09
Benchmark_ShamatonMapMsgpackgen_-88617509603 ns/op1842085.201585622.90
Benchmark_Hprose2_-84848596962 ns/op1701364.67826927.08
Benchmark_FlatBuffers_-859923301160 ns/op1904886.951140642.38
Benchmark_ShamatonArrayMsgpack_-840819541177 ns/op1003284.81408193.59
Benchmark_ShamatonMapMsgpack_-834549241434 ns/op1843604.96635703.98
Benchmark_Protobuf_-831082911533 ns/op1043284.77323264.67
Benchmark_VmihailencoMsgpack_-829205131581 ns/op1844244.62537373.73
Benchmark_CapNProto2_-830690151633 ns/op19217245.01589250.95
Benchmark_GoAvro2Binary_-826845351789 ns/op9410084.80252341.78
Benchmark_JsonIter_-826819331970 ns/op2824165.29757914.74
Benchmark_UgorjiCodecMsgpack_-823876632018 ns/op18219284.82434551.05
Benchmark_EasyJson_-819413302071 ns/op30310084.02588612.05
Benchmark_Ikea_-826798082089 ns/op1103445.60294776.07
Benchmark_Hprose_-821152002104 ns/op1707164.45360642.94
Benchmark_UgorjiCodecBinc_-818256022300 ns/op19021044.20346861.09
Benchmark_CapNProto_-829972322354 ns/op19245847.06575460.51
Benchmark_XDR_-818523012543 ns/op1836714.71340803.79
Benchmark_Bson_-818964202655 ns/op2206005.03417214.42
Benchmark_FastJson_-820076422669 ns/op26722085.36537241.21
Benchmark_Binary_-814576173063 ns/op1226804.46177824.50
Benchmark_MongoBson_-814877553212 ns/op2206484.78327304.96
Benchmark_Json_-814884343405 ns/op3035595.07451446.09
Benchmark_Sereal_-88592045186 ns/op26418084.46226822.87
Benchmark_GoAvro2Text_-87554235748 ns/op26720564.34202152.80
Benchmark_GoAvro_-86500167918 ns/op9432725.1561102.42
Benchmark_SSZNoTimeNoStringNoFloatA_-833518613111 ns/op11016244.3936878.07
Benchmark_Gogojsonpb_-818979424155 ns/op25264944.5847863.72
Benchmark_Gob_-829444335056 ns/op327938410.3296343.74

Issues

The benchmarks can also be run with validation enabled.

VALIDATE=1 go test -bench='.*' ./

Unfortunately, several of the serializers exhibit issues:

  1. (minor) BSON drops sub-microsecond precision from time.Time.
  2. (minor) Ugorji Binc Codec drops the timezone name (eg. "EST" -> "-0500") from time.Time.
--- FAIL: BenchmarkBsonUnmarshal-8
    serialization_benchmarks_test.go:115: unmarshaled object differed:
        &{20b999e3621bd773 2016-01-19 14:05:02.469416459 -0800 PST f017c8e9de 4 true 0.20887343719329818}
        &{20b999e3621bd773 2016-01-19 14:05:02.469 -0800 PST f017c8e9de 4 true 0.20887343719329818}
--- FAIL: BenchmarkUgorjiCodecBincUnmarshal-8
    serialization_benchmarks_test.go:115: unmarshaled object differed:
        &{20a1757ced6b488e 2016-01-19 14:05:15.69474534 -0800 PST 71f3bf4233 0 false 0.8712180830484527}
        &{20a1757ced6b488e 2016-01-19 14:05:15.69474534 -0800 -0800 71f3bf4233 0 false 0.8712180830484527}

All other fields are correct however.

Additionally, while not a correctness issue, FlatBuffers, ProtoBuffers, Cap'N'Proto and ikeapack do not support time types directly. In the benchmarks an int64 value is used to hold a UnixNano timestamp.

  1. (major) Goprotobuf has been disabled in the above, as it is no longer maintained and is incompatible with the latest changes to Google's Protobuf package. See discussions: 1, 2.
panic: protobuf tag not enough fields in ProtoBufA.state:

goroutine 148 [running]:
github.com/gogo/protobuf/proto.(*unmarshalInfo).computeUnmarshalInfo(0xc0000d9c20)
 /home/ken/src/go/pkg/mod/github.com/gogo/protobuf@v1.3.2/proto/table_unmarshal.go:341 +0x135f
github.com/gogo/protobuf/proto.(*unmarshalInfo).unmarshal(0xc0000d9c20, {0xcff820?}, {0xc000122fc0, 0x35, 0x35})
 /home/ken/src/go/pkg/mod/github.com/gogo/protobuf@v1.3.2/proto/table_unmarshal.go:138 +0x67
github.com/gogo/protobuf/proto.(*InternalMessageInfo).Unmarshal(0xc00013a8c0?, {0xe6d5f0, 0xc000114060}, {0xc000122fc0?, 0x35?, 0x35?})
 /home/ken/src/go/pkg/mod/github.com/gogo/protobuf@v1.3.2/proto/table_unmarshal.go:63 +0xd0
github.com/gogo/protobuf/proto.(*Buffer).Unmarshal(0xc00009fe28, {0xe6d5f0, 0xc000114060})
 /home/ken/src/go/pkg/mod/github.com/gogo/protobuf@v1.3.2/proto/decode.go:424 +0x153
github.com/gogo/protobuf/proto.Unmarshal({0xc000122fc0, 0x35, 0x35}, {0xe6d5f0, 0xc000114060})
 /home/ken/src/go/pkg/mod/github.com/gogo/protobuf@v1.3.2/proto/decode.go:342 +0xe6
github.com/alecthomas/go_serialization_benchmarks.Benchmark_Goprotobuf_Unmarshal(0xc0000d5680)
 /home/ken/src/go/src/github.com/alecthomas/go_serialization_benchmarks/serialization_benchmarks_test.go:853 +0x26a
testing.(*B).runN(0xc0000d5680, 0x1)
 /usr/local/go/src/testing/benchmark.go:193 +0x102
testing.(*B).run1.func1()
 /usr/local/go/src/testing/benchmark.go:233 +0x59
created by testing.(*B).run1
 /usr/local/go/src/testing/benchmark.go:226 +0x9c
exit status 2
FAIL github.com/alecthomas/go_serialization_benchmarks 61.159s