Golang高性能json包:easyjson

简介

easyjson是什么呢? 根据官网介绍,easyjson是提供高效快速且易用的结构体structs<-->json转换包。easyjson并没有使用反射方式实现,所以性能比其他的json包该4-5倍,比golang 自带的json包快2-3倍。 easyjson目标是维持生成代码简单,以致于它可以轻松地进行优化或固定。

安装

goget-ugithub.com/mailru/easyjson/goinstallgithub.com/mailru/easyjson/easyjsonorgobuild-oeasyjsongithub.com/mailru/easyjson/easyjson

验证是否安装成功。

$easyjson
UsageofD:\Code\go\bin\easyjson.exe:
-allgeneratemarshaler/unmarshalersforallstructsinafile
-build_tagsstringbuildtagstoaddtogeneratedfile
-leave_tempsdonotdeletetemporaryfiles
-lower_camel_caseuselowerCamelCasenamesinsteadofCamelCasebydefault
-no_std_marshalersdon'tgenerateMarshalJSON/UnmarshalJSONfuncs
-noformatdonotrun'gofmt-w'onoutputfile
-omit_emptyomitemptyfieldsbydefault

string
specifythefilenameoftheoutput
-pkgprocessthewholepackageinsteadofjustthegivenfile
-snake_caseusesnake_casenamesinsteadofCamelCasebydefault
-stubsonlygeneratestubsformarshaler/unmarshalerfuncs

其中有几个选项需要注意:

-lower_camel_case:将结构体字段field首字母改为小写。如Name=>name。
-build_tagsstring:将指定的string生成生成的go文件头部。
-no_std_marshalers:不为结构体生成MarshalJSON/UnmarshalJSON函数。
-omit_empty:没有赋值的field可以不生成到json,否则field为该字段类型的认值。-output_filename:定义生成文件名称。-pkg:对包内指定有`//easyjson:json`结构体生成对应的easyjson配置。-snke_case:可以下划线的field如`Name_Student`改为`name_student`。

使用

记得在需要使用easyjson的结构体上加上//easyjson:json。 如下:

//easyjson:jsontypeSchoolstruct{Namestring`json:"name"`
Addrstring`json:"addr"`}//easyjson:jsontypestudentstruct{
Idint`json:"id"`
Namestring`json:"s_name"`
SchoolSchool`json:"s_chool"`
Birthdaytime.Time`json:"birthday"`}

在结构体包下执行

easyjson-allstudent.go

此时在该目录下出现一个新的文件

//Codegeneratedbyeasyjsonformarshaling/unmarshaling.DONOTEDIT.packageeasyjsonimport(
json"encoding/json"
easyjson"github.com/mailru/easyjson"
jlexer"github.com/mailru/easyjson/jlexer"
jwriter"github.com/mailru/easyjson/jwriter")//suppressunusedpackagewarningvar(
_*json.RawMessage
_*jlexer.Lexer
_*jwriter.Writer
_easyjson.Marshaler)funceasyjsonB83d7b77DecodeStudygoEasyjson(in*jlexer.Lexer,out*Student){
isTopLevel:=in.Isstart()ifin.IsNull(){ifisTopLevel{in.Consumed()
}in.Skip()return
}in.Delim('{')for!in.IsDelim('}'){
key:=in.UnsafeString()in.WantColon()ifin.IsNull(){in.Skip()in.WantComma()continue
}switchkey{case"id":out.Id=int(in.Int())case"s_name":out.Name=string(in.String())case"s_chool":
easyjsonB83d7b77DecodeStudygoEasyjson1(in,&out.School)case"birthday":ifdata:=in.Raw();in.Ok(){in.AddError((out.Birthday).UnmarshalJSON(data))
}default:in.SkipRecursive()
}in.WantComma()
}in.Delim('}')ifisTopLevel{in.Consumed()
}
}funceasyjsonB83d7b77EncodeStudygoEasyjson(out*jwriter.Writer,inStudent){out.RawByte('{')
first:=true
_=firstif!first{out.RawByte(',')
}
first=false
out.RawString("\"id\":")out.Int(int(in.Id))if!first{out.RawByte(',')
}
first=false
out.RawString("\"s_name\":")out.String(string(in.Name))if!first{out.RawByte(',')
}
first=false
out.RawString("\"s_chool\":")
easyjsonB83d7b77EncodeStudygoEasyjson1(out,in.School)if!first{out.RawByte(',')
}
first=false
out.RawString("\"birthday\":")out.Raw((in.Birthday).MarshalJSON())out.RawByte('}')
}//MarshalJSONsupportsjson.Marshalerinterfacefunc(vStudent)MarshalJSON()([]byte,error){
w:=jwriter.Writer{}
easyjsonB83d7b77EncodeStudygoEasyjson(&w,v)returnw.Buffer.BuildBytes(),w.Error
}//MarshalEasyJSONsupportseasyjson.Marshalerinterfacefunc(vStudent)MarshalEasyJSON(w*jwriter.Writer){
easyjsonB83d7b77EncodeStudygoEasyjson(w,v)
}//UnmarshalJSONsupportsjson.Unmarshalerinterfacefunc(v*Student)UnmarshalJSON(data[]byte)error{
r:=jlexer.Lexer{Data:data}
easyjsonB83d7b77DecodeStudygoEasyjson(&r,v)returnr.Error()
}//UnmarshalEasyJSONsupportseasyjson.Unmarshalerinterfacefunc(v*Student)UnmarshalEasyJSON(l*jlexer.Lexer){
easyjsonB83d7b77DecodeStudygoEasyjson(l,v)
}funceasyjsonB83d7b77DecodeStudygoEasyjson1(in*jlexer.Lexer,out*School){
isTopLevel:=in.Isstart()ifin.IsNull(){ifisTopLevel{in.Consumed()
}in.Skip()return
}in.Delim('{')for!in.IsDelim('}'){
key:=in.UnsafeString()in.WantColon()ifin.IsNull(){in.Skip()in.WantComma()continue
}switchkey{case"name":out.Name=string(in.String())case"addr":out.Addr=string(in.String())default:in.SkipRecursive()
}in.WantComma()
}in.Delim('}')ifisTopLevel{in.Consumed()
}
}funceasyjsonB83d7b77EncodeStudygoEasyjson1(out*jwriter.Writer,inSchool){out.RawByte('{')
first:=true
_=firstif!first{out.RawByte(',')
}
first=false
out.RawString("\"name\":")out.String(string(in.Name))if!first{out.RawByte(',')
}
first=false
out.RawString("\"addr\":")out.String(string(in.Addr))out.RawByte('}')
}

现在可以写一个测试类啦。

packagemainimport("studygo/easyjson"
"time"
"fmt")funcmain(){
s:=easyjson.Student{
Id:11,Name:"qq",School:easyjson.School{
Name:"CUMT",Addr:"xz",},Birthday:time.Now(),}
bt,err:=s.MarshalJSON()
fmt.Println(string(bt),err)
json:=`{"id":11,"s_name":"qq","s_chool":{"name":"CUMT","addr":"xz"},"birthday":"2017-08-04T20:58:07.9894603+08:00"}`
ss:=easyjson.Student{}
ss.UnmarshalJSON([]byte(json))
fmt.Println(ss)
}

运行结果:

{"id":11,"birthday":"2017-08-04T20:58:07.9894603+08:00"}<nil>
{121{CwwwwwwwUMTxzwwwww}2017-08-0420:52:03.4066002+0800CST}

相关文章

什么是Go的接口? 接口可以说是一种类型,可以粗略的理解为他...
1、Golang指针 在介绍Golang指针隐式间接引用前,先简单说下...
1、概述 1.1&#160;Protocol buffers定义 Protocol buffe...
判断文件是否存在,需要用到"os"包中的两个函数: os.Stat(...
1、编译环境 OS :Loongnix-Server Linux release 8.3 CPU指...
1、概述 Golang是一种强类型语言,虽然在代码中经常看到i:=1...