再测Golang JSON类库
写项目一直需要进行序列化,听到了,也看到了很多同学老师对各个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_kaleidoscope.dev.igetget.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,}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_kaleidoscope.dev.igetget.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://blog.51cto.com/qiangmzsx/2070603
再测Golang JSON类库相关推荐
- 再测Golang的JSON库
2019独角兽企业重金招聘Python工程师标准>>> 写项目一直需要进行序列化,听到了,也看到了很多同学老师对各个golang的json库进行测评.那本人为什么还要继续进行这一次测 ...
- 【golang程序包推荐分享】分享亿点点golang json操作及myJsonMarshal程序包开发的踩坑经历 :)
目录[阅读时间:约5分钟] 一.概述 1.Json的作用 2.Go官方 encoding/json 包 3. golang json的主要操作 二.Json Marshal:将数据编码成json字符串 ...
- 两款JSON类库Jackson与JSON-lib的性能对比(新增第三款测试)
本篇文章主要介绍了"两款JSON类库Jackson与JSON-lib的性能对比(新增第三款测试)",主要涉及到两款JSON类库Jackson与JSON-lib的性能对比(新增第三款 ...
- 三款JSON类库Jackson,Gson与JSON-lib的性能对比
近日做一些性能优化工作,在挑选JSON类库时,发现除了一般常用的JSON-lib外,还有一款号称性能最快的JSON处理器Jackson,于是用上了刚学会的JMeter,对这两个类库进行了简单的性能对比 ...
- 常见的JSON类库简单使用和遇到的问题
1.常见的json类库 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式.易于人阅读和编写,可以在多种语言之间进行数据交换. 选择一个合适的JSON库要从多个 ...
- Atitit.json类库的设计与实现 ati json lib
Atitit.json类库的设计与实现 ati json lib 1. 目前jsonlib库可能有问题,可能版本冲突,抛出ex1 2. 解决之道:1 2.1. 自定义json解析库,使用多个复合的js ...
- golang json数组拼接
2016年06月16日 15:38:25 阅读数:2575 标签: golang json 数组 更多 个人分类: golang func main() {a := []byte(`{"P ...
- Golang Json文件解析为结构体工具-json2go
代码地址如下: http://www.demodashi.com/demo/14946.html 概述 json2go是一个基于Golang开发的轻量json文件解析.转换命令行工具,目前支持转换输出 ...
- 学python前要学c吗_目前python熟练 ,想再学golang 需要先学c吗?
首先需要题主记住一个结论:编程技术是一个技能.既然是一项技能,就像骑自行车一样,是可以通过不断的练习来获得这项技能. 因此,题主在日后的工作中,不要再提自己属于野生自学非科班学生这个背景,每当你这么说 ...
最新文章
- C++ __gnu_pbds(平板电视)超详细教程(C++内置的平衡树,字典树,hash)
- 【Luogu3383】【模板】线性筛素数
- 使用Amalgamate将C/C++项目合并成一个.h/.c[pp]文件
- Doracle.jdbc.J2EE13Compliant=true
- Spring:笔记整理(1)——HelloWorld
- Java基础学习总结(119)——Java8 JVM与Java7 JVM比较
- CSUOJ 1010: Water Drinking
- Linux内核学习篇三:中断处理 -- asm.s和traps.c
- pdf加水印方法,快速给pdf加水印
- WSAGetLastError错误列表
- Android 项目正式签名打包教程
- 异形双柱体阵列纳米粒:针状/花状纳米粒子/纳米金星/金笼/金壳/三角形纳米金
- rhythmbox插件开发笔记1:简介入门
- Aseprite学习/技巧
- join left loke mysql_mysql监控---慢语句查询
- k8s集群二进制部署 1.17.3
- 【应用】Markdown 在线阅读器
- bugku---game1
- 文案是否有违禁词查询
- golang 读取Response Body 超时问题
热门文章
- mysql多数据库_mysql 多端口及主从数据库
- Java题目筛选器_【024期】JavaWeb面试题(五):Filter和Listener
- 韩顺平mysql优化笔记_韩顺平 mysql优化笔记.doc
- centos7安装jdk只有几k的坑
- mysql 主键冲突 多个事务回滚_MySQL实战45讲Day38----自增主键不是连续的原因
- python玩王者荣耀皮肤碎片怎么获得_教你用Python代码免费获取王者荣耀全英雄皮肤...
- 查看显卡信号_既然大家说装了win10,就不用鲁大师监测显卡温度,为什么呢
- 两个股市真理之间的矛盾
- 机房收费系统个人重构版:透过文档谈文档驱动开发
- 年轻人,你的小米和宜家,要在一起了