Golang高性能json包:easyjson

梦朝思夕 · · 876 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

简介

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

安装

go get -u github.com/mailru/easyjson/go install  github.com/mailru/easyjson/easyjsonorgo build -o easyjson github.com/mailru/easyjson/easyjson

验证是否安装成功。

$ easyjson
Usage of D:\Code\go\bin\easyjson.exe:
  -all        generate marshaler/unmarshalers for all structs in a file
  -build_tags string        build tags to add to generated file
  -leave_temps        do not delete temporary files
  -lower_camel_case        use lowerCamelCase names instead of CamelCase by default
  -no_std_marshalers        don't generate MarshalJSON/UnmarshalJSON funcs
  -noformat        do not run 'gofmt -w' on output file
  -omit_empty        omit empty fields by default

   string
        specify the filename of the output
  -pkg        process the whole package instead of just the given file
  -snake_case        use snake_case names instead of CamelCase by default
  -stubs        only generate stubs for marshaler/unmarshaler funcs

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

-lower_camel_case:将结构体字段field首字母改为小写。如Name=>name。  
-build_tags string:将指定的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:jsontype School struct {    Name string        `json:"name"`
    Addr string        `json:"addr"`}//easyjson:jsontype Student struct {
    Id       int       `json:"id"`
    Name     string    `json:"s_name"`
    School   School    `json:"s_chool"`
    Birthday time.Time `json:"birthday"`}

在结构体包下执行

easyjson  -all student.go

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

// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.package easyjsonimport (
    json "encoding/json"
    easyjson "github.com/mailru/easyjson"
    jlexer "github.com/mailru/easyjson/jlexer"
    jwriter "github.com/mailru/easyjson/jwriter")// suppress unused package warningvar (
    _ *json.RawMessage
    _ *jlexer.Lexer
    _ *jwriter.Writer
    _ easyjson.Marshaler)func easyjsonB83d7b77DecodeStudygoEasyjson(in *jlexer.Lexer, out *Student) {
    isTopLevel := in.IsStart()    if in.IsNull() {        if isTopLevel {            in.Consumed()
        }        in.Skip()        return
    }    in.Delim('{')    for !in.IsDelim('}') {
        key := in.UnsafeString()        in.WantColon()        if in.IsNull() {            in.Skip()            in.WantComma()            continue
        }        switch key {        case "id":            out.Id = int(in.Int())        case "s_name":            out.Name = string(in.String())        case "s_chool":
            easyjsonB83d7b77DecodeStudygoEasyjson1(in, &out.School)        case "birthday":            if data := in.Raw(); in.Ok() {                in.AddError((out.Birthday).UnmarshalJSON(data))
            }        default:            in.SkipRecursive()
        }        in.WantComma()
    }    in.Delim('}')    if isTopLevel {        in.Consumed()
    }
}func easyjsonB83d7b77EncodeStudygoEasyjson(out *jwriter.Writer, in Student) {    out.RawByte('{')
    first := true
    _ = first    if !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('}')
}// MarshalJSON supports json.Marshaler interfacefunc (v Student) MarshalJSON() ([]byte, error) {
    w := jwriter.Writer{}
    easyjsonB83d7b77EncodeStudygoEasyjson(&w, v)    return w.Buffer.BuildBytes(), w.Error
}// MarshalEasyJSON supports easyjson.Marshaler interfacefunc (v Student) MarshalEasyJSON(w *jwriter.Writer) {
    easyjsonB83d7b77EncodeStudygoEasyjson(w, v)
}// UnmarshalJSON supports json.Unmarshaler interfacefunc (v *Student) UnmarshalJSON(data []byte) error {
    r := jlexer.Lexer{Data: data}
    easyjsonB83d7b77DecodeStudygoEasyjson(&r, v)    return r.Error()
}// UnmarshalEasyJSON supports easyjson.Unmarshaler interfacefunc (v *Student) UnmarshalEasyJSON(l *jlexer.Lexer) {
    easyjsonB83d7b77DecodeStudygoEasyjson(l, v)
}func easyjsonB83d7b77DecodeStudygoEasyjson1(in *jlexer.Lexer, out *School) {
    isTopLevel := in.IsStart()    if in.IsNull() {        if isTopLevel {            in.Consumed()
        }        in.Skip()        return
    }    in.Delim('{')    for !in.IsDelim('}') {
        key := in.UnsafeString()        in.WantColon()        if in.IsNull() {            in.Skip()            in.WantComma()            continue
        }        switch key {        case "name":            out.Name = string(in.String())        case "addr":            out.Addr = string(in.String())        default:            in.SkipRecursive()
        }        in.WantComma()
    }    in.Delim('}')    if isTopLevel {        in.Consumed()
    }
}func easyjsonB83d7b77EncodeStudygoEasyjson1(out *jwriter.Writer, in School) {    out.RawByte('{')
    first := true
    _ = first    if !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('}')
}

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

package mainimport (    "studygo/easyjson"
    "time"
    "fmt")func main(){
    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,"s_name":"qq","s_chool":{"name":"CUMT","addr":"xz"},"birthday":"2017-08-04T20:58:07.9894603+08:00"} <nil>
{121  {CwwwwwwwUMT xzwwwww} 2017-08-04 20:52:03.4066002 +0800 CST}



有疑问加站长微信联系(非本文作者)

本文来自:51CTO博客

感谢作者:梦朝思夕

查看原文:Golang高性能json包:easyjson

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

876 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传