几种Go序列化库的性能比较

序列化库在网络传输,RPC,数据库访问等环境中经常用到,它的性能的好坏直接影响着整个产品的性能。

本文列出了几种高性能的Go语言的序列化库,并通过一个简单的无循环引用的数据结构测试它们的性能。

测试代码:gosercomp at github

测试的 Serializers

以golang自带的encoding/json和encoding/xml为基准,测试以下性能比较好的几种序列化库。

排除的 Serializers

基于 alecthomas 已有的测试,下面的库由于性能的原因没有进行测试。

测试环境

对于github.com/youtube/vitess/go/bson,你可能需要安装goimports和codegen:

1234
go get github.com/youtube/vitess/go/bsongo get golang.org/x/tools/cmd/goimportsgo get github.com/youtube/vitess/tree/master/go/cmd/bsongenbsongen -file data.go -o bson_data.go -type ColorGroup

对于MessagePack,你需要安装库以及利用go generate生成相关的类:

12
go get github.com/tinylib/msgpgo generate

对于ProtoBuf,你需要安装protoc编译器,以及protoc库以及生成相关的类:

12
go get github.com/golang/protobufgo generate

对于gogo/protobuf,你需要安装库以及生成相关的类:

123
go get github.com/gogo/protobuf/gogoprotogo get github.com/gogo/protobuf/protoc-gen-gofastgo generate

对于flatbuffers,你需要安装flatbuffers编译器, 以及flatbuffers库:

12
github.com/google/flatbuffers/gogo generate

事实上,这里通过go generate生成相关的类,你也可以通过命令行生成,请参考data.go中的注释。

运行下面的命令测试:

1
go test -bench=.

测试数据

所有的测试基于以下的struct,自动生成的struct, 比如protobuf也和此结构基本一致。

12345
type ColorGroup struct {	ID     int `json:"id" xml:"id,attr""`	Name   string `json:"name" xml:"name"`	Colors []string `json:"colors" xml:"colors"`}

性能测试结果

1234567891011121314151617181920212223
benchmark _name                               iter                 time/iter ------------------------------------------------------------------------------BenchmarkMarshalByJson-4                      1000000              1877 ns/opBenchmarkUnmarshalByJson-4                    300000               4099 ns/opBenchmarkMarshalByXml-4                       200000               8315 ns/opBenchmarkUnmarshalByXml-4                     100000               26627 ns/opBenchmarkMarshalByBson-4                      500000               3518 ns/opBenchmarkUnmarshalByBson-4                    1000000              1778 ns/opBenchmarkMarshalByMsgp-4                      5000000              292 ns/opBenchmarkUnmarshalByMsgp-4                    3000000              543 ns/opBenchmarkMarshalByProtoBuf-4                  1000000              1011 ns/opBenchmarkUnmarshalByProtoBuf-4                1000000              1750 ns/opBenchmarkMarshalByGogoProtoBuf-4              5000000              220 ns/opBenchmarkUnmarshalByGogoProtoBuf-4            2000000              901 ns/opBenchmarkMarshalByFlatBuffers-4               3000000              566 ns/opBenchmarkUnmarshalByFlatBuffers-4             50000000             9.54 ns/opBenchmarUmByFlatBuffers_withFields-4          3000000              554 ns/op

多次测试结果差不多。

从结果上上来看,MessagePack
,gogo/protobuf
,和flatbuffers
差不多,这三个优秀的库在序列化和反序列化上各有千秋,而且都是跨语言的。

从便利性上来讲,你可以选择MessagePack
gogo/protobuf
都可以,两者都有大厂在用。

flatbuffers
有点反人类,因为它的操作很底层,而且从结果上来看,序列化的性能要差一点。但是它有一个好处,那就是如果你只需要特定的字段,

你无须将所有的字段都反序列化。从结果上看,不反序列化字段每个调用只用了9.54纳秒,这是因为字段只有在被访问的时候才从byte数组转化为相应的类型。

因此在特殊的场景下,它可以提高N被的性能。但是序列化的代码的面相太难看了。

发表评论

关闭菜单