Golang高性能json包:easyjson

简介

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}
时间: 2024-10-12 16:36:56

Golang高性能json包:easyjson的相关文章

golang:高性能消息队列moonmq的简单使用

在上一篇moonmq的介绍中(这里),我只简短的罗列了一些moonmq的设计想法,可是对于怎样使用并没有具体说明,公司同事无法非常好的使用. 对于moonmq的使用,事实上非常easy,例子代码在这里,我们仅仅须要处理好broker,consumer以及publisher的关系就能够了. 首先,我们须要启动一个broker,由于moonmq如今仅仅支持tcp的自己定义协议,所以broker启动的时候须要指定一个listen address. #启动broker ./simple_broker -

YxdJSON - Delphi 高性能 JSON 库(支持RTTI和序列化操作)

Delphi 高性能 JSON 库(支持RTTI和序列化操作) 支持平台: Windows, Android, iOS, Mac OS https://github.com/yangyxd/YxdJson

Go_14:GoLang中 json、map、struct 之间的相互转化

1. golang 中 json 转 struct <1. 使用 json.Unmarshal 时,结构体的每一项必须是导出项(import field).也就是说结构体的 key 对应的首字母必须为大写.请看下面的例子: package commontest import ( "testing" "encoding/json" ) type Person struct { name string age int } func TestStruct2Json(

两层嵌套的JSON包的解法

由于后台的变态,有时候会出现两层甚至多层嵌套的JSON包. 一层的很好解,而且我看过一些比较大的网站新闻接口返回的JSON包也仅仅是一层的. 比如下图所示一层的包 代码也很简单直观 dict = [data objectFromJSONData]; // 这里可能会转换失败,还需要接着做判断 _dinnArray = [[NSMutableArray alloc] init]; _dataArray = [dict objectForKey:@"data"]; for (NSDicti

golang的json序列化

json就是简单的数据交换格式,语法类似javascript的对象和列表,是最常见的后端和运行在网页上的js之间的通信格式. encoding: 编码json数据需要使用到Marshal()函数. func Marshal(v interface{}) ([]byte, error) type Message struct { Name string Body string Time int64 } m := Message{"Alice", "Hello", 12

golang的sync包例子

package main import ( "fmt" "sync" ) var wg sync.WaitGroup func asyncTestFunc() { for i := 0; i < 100; i++ { fmt.Println(i) } wg.Done() } func main() { wg.Add(1) go asyncTestFunc() wg.Wait() } golang的sync包例子

golang的io包

package io import "io" io包提供了对I/O原语的基本接口.本包的基本任务是包装这些原语已有的实现(如os包里的原语),使之成为共享的公共接口,这些公共接口抽象出了泛用的函数并附加了一些相关的原语的操作. 因为这些接口和原语是对底层实现完全不同的低水平操作的包装,除非得到其它方面的通知,客户端不应假设它们是并发执行安全的. Index Variables type Reader type Writer type Closer type Seeker type Re

Spring mvc4使用JSON包变更

spring MVC4以上,使用的json包有变更. 使用之前的json包出包java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/JsonProcessingException错误. 新用到包为jackson-annotations-2.5.0.jar,jackson-core-2.5.0.jar,jackson-databind-2.5.0.jar spring-servlet.xml里面也有变动 <!-- 用于将对象转换为 J

使用JSONArray.fromObject()方法和引入net.sf.json包所需要的jar包支持

关于使用JSONArray.fromObject()方法和引入net.sf.json包所需要的jar包支持. net.sf.json的下载地址 最新版本:http://sourceforge.net/projects/json-lib/files/json-lib/ 本次选择 json-lib-2.3-jdk15.jar 版本 最新的是2.4的版本,本次使用的是 json-lib-2.3-jdk15.jar: json-lib还需要以下依赖包: jakarta commons-lang 2.5