再测Golang的JSON库
2019独角兽企业重金招聘Python工程师标准>>>
写项目一直需要进行序列化,听到了,也看到了很多同学老师对各个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// easyjsonas = 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)// stdasstd = 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 = iGobEncode(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 = ierr := 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 = ierr := 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 = ierr := 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 = ierr := 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 = ierr := 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 = ierr := 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 = ierr := 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 = ierr := 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 = ierr := 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 = ierr := 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 = iGobDecode(asGonBytes, &tmp)}
}func Benchmark_GOB_Decode2(b *testing.B) {tmp := Service{}for i := 0; i < b.N*10; i++ {as.Port = iGobDecode(serviceGonBytes, &tmp)}
}
执行命令:
go test -bench=".*"
测评结果;
$ go test -bench=".*"
Benchmark_STD_Marshal1-4 50000 31224 ns/op
Benchmark_STD_Marshal2-4 30000 49598 ns/op
Benchmark_EASYJSON_STD_Marshal1-4 30000 45778 ns/op
Benchmark_EASYJSON_STD_Marshal2-4 30000 50440 ns/op
Benchmark_EASYJSON_Marshal1-4 100000 14387 ns/op
Benchmark_EASYJSON_Marshal2-4 100000 16009 ns/op
Benchmark_ITERATOR_Marshal1-4 100000 14899 ns/op
Benchmark_ITERATOR_Marshal2-4 100000 21629 ns/op
Benchmark_FFJSON_Marshal1-4 50000 31633 ns/op
Benchmark_FFJSON_Marshal2-4 30000 51668 ns/op
Benchmark_GOB_Encode1-4 20000 97099 ns/op
Benchmark_GOB_Encode2-4 10000 153158 ns/op
Benchmark_STD_Unmarshal1-4 20000 89211 ns/op
Benchmark_STD_Unmarshal2-4 20000 76442 ns/op
Benchmark_EASYJSON_STD_Unmarshal1-4 30000 57695 ns/op
Benchmark_EASYJSON_STD_Unmarshal2-4 20000 66269 ns/op
Benchmark_EASYJSON_Unmarshal1-4 100000 19028 ns/op
Benchmark_EASYJSON_Unmarshal2-4 100000 22035 ns/op
Benchmark_ITERATOR_UnMarshal1-4 50000 35942 ns/op
Benchmark_ITERATOR_UnMarshal2-4 50000 36462 ns/op
Benchmark_FFJSON_UnMarshal1-4 20000 80290 ns/op
Benchmark_FFJSON_UnMarshal2-4 20000 78431 ns/op
Benchmark_GOB_Decode1-4 3000 377698 ns/op
Benchmark_GOB_Decode2-4 3000 463472 ns/op
PASS
ok studygo/jsonbench 49.174s
结论
- 哪一个类库最快?
答:是测评类库中最快的。速度:easyjson => iterator => encoding/json => ffjson - 是否存在坑?
答:easyjson
有一个坑,从代码中可以看到Benchmark_EASYJSON_STD_*
的方法,是因为easyjson生成的代码中已经包含了MarshalJSON
和UnmarshalJSON
方法,那么只要对这些结构体执行json.marshalJSON
和json.UnmarshalJSON
都会默认调用easyjson生成的方法。本人运行多次,都会发现调用easyjson生成的MarshalJSON
方法比标准库中的慢一些达到50%左右,但是调用easyjson
生成的UnmarshalJSON
比标准库的快一些大概20%。 - 如何选择?
答:easyjson
速度虽然比较快,但也是存在一些不适合的场景,比如如果需要对interface
接口进行序列化时候。所以建议采用easyjson
与标准库结合。
转载于:https://my.oschina.net/qiangmzsx/blog/1620596
再测Golang的JSON库相关推荐
- 再测Golang JSON类库
写项目一直需要进行序列化,听到了,也看到了很多同学老师对各个golang的json库进行测评.那本人为什么还要继续进行这一次测评呢? 因为实践过的知识最有说服力,也是属于自己的,我也希望看到本博文的同 ...
- 突然发现一个很好用Golang的json库
2019独角兽企业重金招聘Python工程师标准>>> json 我并不想解释json是什么. 库名 GJSON 点这里去star感谢小哥 下载 $ go get -u github ...
- 推荐一个golang的json库
生成json的库 https://github.com/bennyscetbun/jsongo https://github.com/donnie4w/json4g 转载于:https://www.c ...
- Golang的viper库
Golang的viper库 1.作用 viper 是一个配置解决方案,拥有丰富的特性: 支持 JSON/TOML/YAML/HCL/envfile/Java properties 等多种格式的配置文件 ...
- 为字节节省数十万核的json库sonic
1 sonic产生的背景 为什么要优化? json操作在服务中的cpu开销中占据相当的比重.根据字节所有服务的统计,json序列化和反序列化的开销接近10%,部分服务甚至达到40%. golang现有 ...
- golang高性能日志库zap的使用
本文作者:陈进坚 个人博客:https://jian1098.github.io CSDN博客:https://blog.csdn.net/c_jian 简书:https://www.jianshu. ...
- JAVA中几种常用JSON库性能比较
点击上方"方志朋",选择"置顶公众号" 技术文章第一时间送达! 作者:飞污熊 xncoding.com/2018/01/09/java/jsons.html 本 ...
- Golang实现requests库
Golang实现requests库 简单的封装下,方便使用,像python的requests库一样. Github地址 Github 支持 GET.POST.PUT.DELETE applicatio ...
- Golang 处理 Json(二):解码
golang 编码 json 还比较简单,而解析 json 则非常蛋疼.不像 PHP 一句 json_decode() 就能搞定.之前项目开发中,为了兼容不同客户端的需求,请求的 content-ty ...
最新文章
- 开源项目越来越商业友好,谁来负责开发者友好呢?
- artdialog 异步加载页面 生成验证码
- cout的输出格式初探2
- Android从普通发送和接收短信到对短信进行拦截
- boost的chrono模块最小时间点的测试程序
- 程序员吐槽_阿里程序员回老家被哥们吐槽,破IT就破IT,还阿里巴巴
- C语言程序设计第三次作业
- spring 基于java的配置
- 具有Azure功能的无服务器API
- php继承和重载区别,php继承中方法重载(覆盖)的应用场合
- 如何把开源项目发布到Jcenter
- 高效记忆/形象记忆(15)110数字编码表 91-00
- 【书评】《你好哇,程序员——漫话程序员面试求职、升职加薪、创业与生活》
- 数据库练习题(比较基础)
- 阴阳师自动御魂觉醒超鬼王脚本
- 笔记本打开腾讯会议显示未检测到可用摄像头,但是系统自带相机可以使用
- 笔记本wife DNS服务器未响应,为什么手机已经连接上wifi还是上不了网?
- 数字增加滚动动画用原生js实现的多种方案
- PARAMETERS定义下拉列表--实例参考学习
- 威海南海新区首届“龙腾齐鲁”龙王争霸赛开赛
热门文章
- 聚焦OA品牌:OA产品影响力是选型关键
- vim 打开Linux下文件每一行后面都有^M的样式
- js中document.write的那点事
- c库的rand/random随机数产生函数性能差?
- 做出的C++选择以及背后的原因
- 数据库字段命名及设计规范
- Swagger 生成 PHP restful API 接口文档
- java8中的时间处理6 - 格式化
- 观察者模式C#实现实例(一)
- http://demo.netfoucs.com/jianglonghuang/article/details/44888133