以golang自带的_encoding/json_和_encoding/xml_为基准,测试以下性能比较好的几种序列化库。
- encoding/json
- encoding/xml
- github.com/tinylib/msgp
- github.com/golang/protobuf
- github.com/gogo/protobuf
- github.com/google/flatbuffers
- Apache/Thrift
- Apache/Avro
- andyleap/gencode
- ugorji/go/codec
- go-memdump
- colfer
- zebrapack
- gotiny
- github.com/ugorji/go/codec
- hprose-golang
- vmihailenco/msgpack.v2
- Sereal
基于 alecthomas 已有的测试,下面的库由于性能的原因没有进行测试。
- encoding/gob
- github.com/alecthomas/binary
- github.com/davecgh/go-xdr/xdr
- labix.org/v2/mgo/bson
- github.com/DeDiS/protobuf
- gopkg.in/vmihailenco/msgpack.v2
- bson
go version: 1.8.1
-
对于
MessagePack
,你需要安装库以及利用go generate
生成相关的类:go get github.com/tinylib/msgp go generate
-
对于
ProtoBuf
,你需要安装protoc编译器,以及protoc库以及生成相关的类:go get github.com/golang/protobuf go generate
-
对于
gogo/protobuf
,你需要安装库以及生成相关的类:go get github.com/gogo/protobuf/gogoproto go get -u github.com/gogo/protobuf/protoc-gen-gogofaster go generate
-
对于
flatbuffers
,你需要安装[flatbuffers编译器](https://github.com/google/flatbuffers/releases, 以及flatbuffers库:go get github.com/google/flatbuffers/go go generate
-
对于
thrift
,), 你需要安装thrift编译器以及thrift库:go get git.apache.org/thrift.git/lib/go/thrift go generate
-
对于
Avro
,你需要安装goavro库:go get github.com/linkedin/goavro go generate
-
对于
gencode
,你需要安装gencode库,并使用gencode库的工具产生数据对象:go get github.com/andyleap/gencode bin\gencode.exe go -schema=gencode.schema -package gosercomp
gencode
也是一个高性能的编解码库,提供了代码生成工具,而且产生的数据非常的小。 -
对于
easyjson
,你需要安装easyjson库:go get github.com/mailru/easyjson go generate
-
对于
zebraPack
,你需要安装zebraPack库,并使用zebraPack工具产生数据对象:go get github.com/glycerine/zebrapack go generate zebrapack_data.go
-
对于
ugorji/go/codec
,你需要安装代码生成工具和codec
库:
go get -tags=unsafe -u github.com/ugorji/go/codec/codecgen
go get -tags=unsafe -u github.com/ugorji/go/codec
codecgen.exe -o data_codec.go data.go
ugorji/go/codec
是一个高性能的编解码框架,支持 msgpack、cbor、binc、json等格式。本测试中测试了 cbor 和 msgpack的编解码,可以和上面的 tinylib/msgp
框架进行比较。
事实上,这里通过
go generate
生成相关的类,你也可以通过命令行生成,请参考data.go
中的注释。 但是你需要安装相关的工具,如Thrift,并把它们加入到环境变量Path中
运行下面的命令测试:
go test -bench=. -benchmem
所有的测试基于以下的struct,自动生成的struct, 比如protobuf也和此结构基本一致。
type ColorGroup struct {
ID int `json:"id" xml:"id,attr""`
Name string `json:"name" xml:"name"`
Colors []string `json:"colors" xml:"colors"`
}
`
BenchmarkMarshalByJson-4 1000000 1080 ns/op 376 B/op 4 allocs/op
BenchmarkUnmarshalByJson-4 500000 2659 ns/op 344 B/op 9 allocs/op
BenchmarkMarshalByXml-4 300000 4182 ns/op 4801 B/op 12 allocs/op
BenchmarkUnmarshalByXml-4 100000 16022 ns/op 3139 B/op 75 allocs/op
BenchmarkMarshalByMsgp-4 20000000 115 ns/op 80 B/op 1 allocs/op
BenchmarkUnmarshalByMsgp-4 5000000 289 ns/op 32 B/op 5 allocs/op
BenchmarkMarshalByProtoBuf-4 3000000 489 ns/op 328 B/op 5 allocs/op
BenchmarkUnmarshalByProtoBuf-4 2000000 851 ns/op 400 B/op 11 allocs/op
BenchmarkMarshalByGogoProtoBuf-4 20000000 116 ns/op 48 B/op 1 allocs/op
BenchmarkUnmarshalByGogoProtoBuf-4 3000000 463 ns/op 144 B/op 8 allocs/op
BenchmarkMarshalByFlatBuffers-4 3000000 417 ns/op 16 B/op 1 allocs/op
BenchmarkUnmarshalByFlatBuffers-4 500000000 3.17 ns/op 0 B/op 0 allocs/op
BenchmarkUnmarshalByFlatBuffers_withFields-4 10000000 187 ns/op 0 B/op 0 allocs/op
BenchmarkMarshalByThrift-4 3000000 577 ns/op 64 B/op 1 allocs/op
BenchmarkUnmarshalByThrift-4 1000000 1343 ns/op 656 B/op 11 allocs/op
BenchmarkMarshalByAvro-4 2000000 719 ns/op 56 B/op 7 allocs/op
BenchmarkUnmarshalByAvro-4 300000 3545 ns/op 1680 B/op 63 allocs/op
BenchmarkMarshalByGencode-4 30000000 42.2 ns/op 0 B/op 0 allocs/op
BenchmarkUnmarshalByGencode-4 10000000 170 ns/op 32 B/op 5 allocs/op
BenchmarkMarshalByUgorjiCodecAndCbor-4 2000000 745 ns/op 96 B/op 2 allocs/op
BenchmarkUnmarshalByUgorjiCodecAndCbor-4 2000000 606 ns/op 32 B/op 5 allocs/op
BenchmarkMarshalByUgorjiCodecAndMsgp-4 2000000 698 ns/op 96 B/op 2 allocs/op
BenchmarkUnmarshalByUgorjiCodecAndMsgp-4 3000000 590 ns/op 32 B/op 5 allocs/op
BenchmarkMarshalByUgorjiCodecAndBinc-4 2000000 716 ns/op 96 B/op 2 allocs/op
BenchmarkUnmarshalByUgorjiCodecAndBinc-4 2000000 602 ns/op 32 B/op 5 allocs/op
BenchmarkMarshalByUgorjiCodecAndJson-4 1000000 1055 ns/op 96 B/op 2 allocs/op
BenchmarkUnmarshalByUgorjiCodecAndJson-4 1000000 1063 ns/op 128 B/op 8 allocs/op
BenchmarkMarshalByEasyjson-4 5000000 342 ns/op 128 B/op 1 allocs/op
BenchmarkUnmarshalByEasyjson-4 3000000 551 ns/op 32 B/op 5 allocs/op
BenchmarkMarshalByFfjson-4 2000000 970 ns/op 424 B/op 9 allocs/op
BenchmarkUnmarshalByFfjson-4 1000000 1472 ns/op 480 B/op 13 allocs/op
BenchmarkMarshalByGoMemdump-4 300000 5426 ns/op 1040 B/op 31 allocs/op
BenchmarkUnmarshalByGoMemdump-4 1000000 1313 ns/op 2288 B/op 11 allocs/op
BenchmarkMarshalByColfer-4 50000000 35.2 ns/op 0 B/op 0 allocs/op
BenchmarkUnmarshalByColfer-4 5000000 247 ns/op 96 B/op 6 allocs/op
BenchmarkMarshalByZebrapack-4 20000000 225 ns/op 132 B/op 0 allocs/op
BenchmarkUnmarshalByZebrapack-4 10000000 165 ns/op 0 B/op 0 allocs/op
BenchmarkMarshalByGotiny-4 5000000 373 ns/op 144 B/op 5 allocs/op
BenchmarkUnmarshalByGotiny-4 5000000 269 ns/op 88 B/op 2 allocs/op
BenchmarkMarshalByHprose-4 3000000 478 ns/op 210 B/op 1 allocs/op
BenchmarkUnmarshalByHprose-4 2000000 688 ns/op 288 B/op 9 allocs/op
BenchmarkMarshalBySereal-4 500000 2507 ns/op 792 B/op 22 allocs/op
BenchmarkUnmarshalBySereal-4 2000000 815 ns/op 80 B/op 6 allocs/op
BenchmarkMarshalByMsgpackV2-4 1000000 2025 ns/op 192 B/op 4 allocs/op
BenchmarkUnmarshalByMsgpackv2-4 1000000 1756 ns/op 232 B/op 11 allocs/op
多次测试结果差不多。 从结果上上来看, MessagePack,gogo/protobuf,和flatbuffers差不多,这三个优秀的库在序列化和反序列化上各有千秋,而且都是跨语言的。 从便利性上来讲,你可以选择MessagePack和gogo/protobuf都可以,两者都有大厂在用。 flatbuffers有点反人类,因为它的操作很底层,而且从结果上来看,序列化的性能要差一点。但是它有一个好处,那就是如果你只需要特定的字段, 你无须将所有的字段都反序列化。从结果上看,不反序列化字段每个调用只用了9.54纳秒,这是因为字段只有在被访问的时候才从byte数组转化为相应的类型。 因此在特殊的场景下,它可以提高N被的性能。但是序列化的代码的面相太难看了。
新增加了gencode的测试,它表现相当出色,而且生成的字节也非常的小。
Codec的Unmarshal性能不错,但是Marshal性能不是太好。
colfer的性能也不错,它能够跨Go,Java, Javascript平台。
新加入的zebrapack性能抢眼,不但性能卓越,而且可以实现zero allocation,值得关注。