博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
再测Golang的JSON库
阅读量:6982 次
发布时间:2019-06-27

本文共 8509 字,大约阅读时间需要 28 分钟。

hot3.png

写项目一直需要进行序列化,听到了,也看到了很多同学老师对各个golang的json库进行测评。那本人为什么还要继续进行这一次测评呢? 因为实践过的知识最有说服力,也是属于自己的,我也希望看到本博文的同学老师可以修改和执行测评的代码执行一遍,我相信会有不一定的体会。 本次测评我选择了类库有:

类库

序号 类库 地址 备注
1 encoding/json Golan
2 easyjson github.com/mailru/easyjson
3 ffjson github.com/mailru/easyjson
4 iterator/json github.com/json-iterator/go

主要是针对上述的类型进行,本人采用了对不同的类库使用不同的结构体(仅仅是结构体名称不同,字段顺序和类型一样)。

环境

环境为MacBook Pro(Core i5处理器/8GB内存)go1.8.3 darwin/amd64

代码

bench代码如下:

package jsonbenchimport (	"encoding/gob"	"encoding/json"	"github.com/json-iterator/go"	"github.com/mailru/easyjson"	"github.com/pquerna/ffjson/ffjson"	"testing")var (	iterator = jsoniter.ConfigCompatibleWithStandardLibrary	// easyjson	as = AgentService{		ServiceName:    "kaleidoscope_api",		Version:        "1517558949087295000_1298498081",		ServiceId:      "kaleidoscope.com_v1.2",		Address:        "127.0.0.1",		Port:           80,		Metadata:       map[string]string{},		ConnectTimeOut: 1000,		ConnectType:    "LONG",		ReadTimeOut:    1000,		WriteTimeOut:   1000,		Protocol:       "HTTP",		Balance:        "Random",		Idcs:           "hu,hd,hn",		Converter:      "json",		Retry:          3,	}	service            = as.ToService()	asBytes, _         = json.Marshal(as)	serviceBytes, _    = json.Marshal(service)	asStr              = string(asBytes)	serviceStr         = string(serviceBytes)	asGonBytes, _      = GobEncode(as)	serviceGonBytes, _ = GobEncode(service)	// std	asstd = AgentServiceSTD{		ServiceName:    "kaleidoscope_api",		Version:        "1517558949087295000_1298498081",		ServiceId:      "kaleidoscope.com_v1.2",		Address:        "kaleidoscope.dev.igetget.com",		Port:           80,		Metadata:       map[string]string{},		ConnectTimeOut: 1000,		ConnectType:    "LONG",		ReadTimeOut:    1000,		WriteTimeOut:   1000,		Protocol:       "HTTP",		Balance:        "Random",		Idcs:           "hu,hd,hn",		Converter:      "json",		Retry:          3,	}	servicestd            = asstd.ToServiceSTD()	asBytesstd, _         = json.Marshal(asstd)	serviceBytesstd, _    = json.Marshal(servicestd)	asStrstd              = string(asBytesstd)	serviceStrstd         = string(serviceBytesstd)	asGonBytesstd, _      = GobEncode(asstd)	serviceGonBytesstd, _ = GobEncode(servicestd))// go test -bench=".*"func init() {	gob.Register(AgentService{})}func Benchmark_STD_Marshal1(b *testing.B) {	for i := 0; i < b.N*10; i++ {		_, err := json.Marshal(asstd)		if err != nil {			b.Error(err)		}	}}func Benchmark_STD_Marshal2(b *testing.B) {	for i := 0; i < b.N*10; i++ {		_, err := json.Marshal(servicestd)		if err != nil {			b.Error(err)		}	}}func Benchmark_EASYJSON_STD_Marshal1(b *testing.B) {	for i := 0; i < b.N*10; i++ {		_, err := json.Marshal(as)		if err != nil {			b.Error(err)		}	}}func Benchmark_EASYJSON_STD_Marshal2(b *testing.B) {	for i := 0; i < b.N*10; i++ {		_, err := json.Marshal(service)		if err != nil {			b.Error(err)		}	}}func Benchmark_EASYJSON_Marshal1(b *testing.B) {	for i := 0; i < b.N*10; i++ {		_, err := easyjson.Marshal(as)		if err != nil {			b.Error(err)		}	}}func Benchmark_EASYJSON_Marshal2(b *testing.B) {	for i := 0; i < b.N*10; i++ {		_, err := easyjson.Marshal(service)		if err != nil {			b.Error(err)		}	}}//func Benchmark_ITERATOR_Marshal1(b *testing.B) {	for i := 0; i < b.N*10; i++ {		_, err := iterator.Marshal(asstd)		if err != nil {			b.Error(err)		}	}}func Benchmark_ITERATOR_Marshal2(b *testing.B) {	for i := 0; i < b.N*10; i++ {		_, err := iterator.Marshal(servicestd)		if err != nil {			b.Error(err)		}	}}func Benchmark_FFJSON_Marshal1(b *testing.B) {	for i := 0; i < b.N*10; i++ {		_, err := ffjson.Marshal(asstd)		if err != nil {			b.Error(err)		}	}}func Benchmark_FFJSON_Marshal2(b *testing.B) {	for i := 0; i < b.N*10; i++ {		_, err := ffjson.Marshal(servicestd)		if err != nil {			b.Error(err)		}	}}func Benchmark_GOB_Encode1(b *testing.B) {	for i := 0; i < b.N*10; i++ {		as.Port = i		GobEncode(as)	}}func Benchmark_GOB_Encode2(b *testing.B) {	for i := 0; i < b.N*10; i++ {		GobEncode(service)	}}func Benchmark_STD_Unmarshal1(b *testing.B) {	tmp := AgentServiceSTD{}	for i := 0; i < b.N*10; i++ {		as.Port = i		err := json.Unmarshal(asBytesstd, &tmp)		if err != nil {			b.Error(err)		}	}}func Benchmark_STD_Unmarshal2(b *testing.B) {	tmp := ServiceSTD{}	for i := 0; i < b.N*10; i++ {		as.Port = i		err := json.Unmarshal(serviceBytesstd, &tmp)		if err != nil {			b.Error(err)		}	}}func Benchmark_EASYJSON_STD_Unmarshal1(b *testing.B) {	tmp := AgentService{}	for i := 0; i < b.N*10; i++ {		as.Port = i		err := json.Unmarshal(asBytes, &tmp)		if err != nil {			b.Error(err)		}	}}func Benchmark_EASYJSON_STD_Unmarshal2(b *testing.B) {	tmp := Service{}	for i := 0; i < b.N*10; i++ {		as.Port = i		err := json.Unmarshal(serviceBytes, &tmp)		if err != nil {			b.Error(err)		}	}}func Benchmark_EASYJSON_Unmarshal1(b *testing.B) {	tmp := AgentService{}	for i := 0; i < b.N*10; i++ {		as.Port = i		err := easyjson.Unmarshal(asBytes, &tmp)		if err != nil {			b.Error(err)		}	}}func Benchmark_EASYJSON_Unmarshal2(b *testing.B) {	tmp := Service{}	for i := 0; i < b.N*10; i++ {		as.Port = i		err := easyjson.Unmarshal(serviceBytes, &tmp)		if err != nil {			b.Error(err)		}	}}func Benchmark_ITERATOR_UnMarshal1(b *testing.B) {	tmp := ServiceSTD{}	for i := 0; i < b.N*10; i++ {		as.Port = i		err := iterator.Unmarshal(serviceBytesstd, &tmp)		if err != nil {			b.Error(err)		}	}}func Benchmark_ITERATOR_UnMarshal2(b *testing.B) {	tmp := ServiceSTD{}	for i := 0; i < b.N*10; i++ {		as.Port = i		err := iterator.Unmarshal(serviceBytesstd, &tmp)		if err != nil {			b.Error(err)		}	}}func Benchmark_FFJSON_UnMarshal1(b *testing.B) {	tmp := ServiceSTD{}	for i := 0; i < b.N*10; i++ {		as.Port = i		err := ffjson.Unmarshal(serviceBytesstd, &tmp)		if err != nil {			b.Error(err)		}	}}func Benchmark_FFJSON_UnMarshal2(b *testing.B) {	tmp := ServiceSTD{}	for i := 0; i < b.N*10; i++ {		as.Port = i		err := ffjson.Unmarshal(serviceBytesstd, &tmp)		if err != nil {			b.Error(err)		}	}}func Benchmark_GOB_Decode1(b *testing.B) {	tmp := AgentService{}	for i := 0; i < b.N*10; i++ {		as.Port = i		GobDecode(asGonBytes, &tmp)	}}func Benchmark_GOB_Decode2(b *testing.B) {	tmp := Service{}	for i := 0; i < b.N*10; i++ {		as.Port = i		GobDecode(serviceGonBytes, &tmp)	}}

执行命令:

go test -bench=".*"

测评结果;

$ go test -bench=".*"Benchmark_STD_Marshal1-4                   50000             31224 ns/opBenchmark_STD_Marshal2-4                   30000             49598 ns/opBenchmark_EASYJSON_STD_Marshal1-4          30000             45778 ns/opBenchmark_EASYJSON_STD_Marshal2-4          30000             50440 ns/opBenchmark_EASYJSON_Marshal1-4             100000             14387 ns/opBenchmark_EASYJSON_Marshal2-4             100000             16009 ns/opBenchmark_ITERATOR_Marshal1-4             100000             14899 ns/opBenchmark_ITERATOR_Marshal2-4             100000             21629 ns/opBenchmark_FFJSON_Marshal1-4                50000             31633 ns/opBenchmark_FFJSON_Marshal2-4                30000             51668 ns/opBenchmark_GOB_Encode1-4                    20000             97099 ns/opBenchmark_GOB_Encode2-4                    10000            153158 ns/opBenchmark_STD_Unmarshal1-4                 20000             89211 ns/opBenchmark_STD_Unmarshal2-4                 20000             76442 ns/opBenchmark_EASYJSON_STD_Unmarshal1-4        30000             57695 ns/opBenchmark_EASYJSON_STD_Unmarshal2-4        20000             66269 ns/opBenchmark_EASYJSON_Unmarshal1-4           100000             19028 ns/opBenchmark_EASYJSON_Unmarshal2-4           100000             22035 ns/opBenchmark_ITERATOR_UnMarshal1-4            50000             35942 ns/opBenchmark_ITERATOR_UnMarshal2-4            50000             36462 ns/opBenchmark_FFJSON_UnMarshal1-4              20000             80290 ns/opBenchmark_FFJSON_UnMarshal2-4              20000             78431 ns/opBenchmark_GOB_Decode1-4                     3000            377698 ns/opBenchmark_GOB_Decode2-4                     3000            463472 ns/opPASSok      studygo/jsonbench       49.174s

结论

  1. 哪一个类库最快?
    答:是测评类库中最快的。速度:easyjson => iterator => encoding/json => ffjson
  2. 是否存在坑?
    答:easyjson有一个坑,从代码中可以看到Benchmark_EASYJSON_STD_*的方法,是因为easyjson生成的代码中已经包含了MarshalJSONUnmarshalJSON方法,那么只要对这些结构体执行json.marshalJSONjson.UnmarshalJSON都会默认调用easyjson生成的方法。本人运行多次,都会发现调用easyjson生成的MarshalJSON方法比标准库中的慢一些达到50%左右,但是调用easyjson生成的UnmarshalJSON比标准库的快一些大概20%。
  3. 如何选择?
    答:easyjson速度虽然比较快,但也是存在一些不适合的场景,比如如果需要对interface接口进行序列化时候。所以建议采用easyjson与标准库结合。

转载于:https://my.oschina.net/qiangmzsx/blog/1620596

你可能感兴趣的文章
Selenium学习(14) 判断元素expected_conditions
查看>>
Linux命令之tcpdump
查看>>
(更新)Java + 腾讯企业邮箱 + javamail + SSL 发送邮件
查看>>
组合数据类型综合练习
查看>>
php回调函数callback函数实例
查看>>
示波器测量电源的纹波
查看>>
自定义ListBox,实现单多选切换(复选框)
查看>>
软件测试2019:第八次作业
查看>>
Centos下安装FTP并进行虚拟用户访问方式配置
查看>>
python day09
查看>>
拆系数FFT及其部分优化
查看>>
cocos2dx3.8 ios打包脚本编写
查看>>
wordpress搭建博客上传begin主题The themes is locked to another domain
查看>>
2019-04-16 SpringMVC 学习笔记
查看>>
C10K问题
查看>>
慕课网3-13编程练习:采用flex弹性布局制作页面主导航
查看>>
线程中死锁的demo
查看>>
canvas-7globleCompositeOperation.html
查看>>
Java并发(具体实例)——几个例子
查看>>
【待补】java开发Web Service
查看>>