123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 |
- /*
- Each test should process 2.4kb json record (based on Clearbit API)
- It should read multiple nested fields and 1 array
- */
- package benchmark
- import (
- "encoding/json"
- "testing"
- "github.com/Jeffail/gabs"
- "github.com/a8m/djson"
- "github.com/antonholmquist/jason"
- "github.com/bitly/go-simplejson"
- "github.com/buger/jsonparser"
- jlexer "github.com/mailru/easyjson/jlexer"
- "github.com/mreiferson/go-ujson"
- "github.com/pquerna/ffjson/ffjson"
- "github.com/ugorji/go/codec"
- // "fmt"
- "bytes"
- "errors"
- )
- /*
- github.com/buger/jsonparser
- */
- func BenchmarkJsonParserMedium(b *testing.B) {
- for i := 0; i < b.N; i++ {
- jsonparser.Get(mediumFixture, "person", "name", "fullName")
- jsonparser.GetInt(mediumFixture, "person", "github", "followers")
- jsonparser.Get(mediumFixture, "company")
- jsonparser.ArrayEach(mediumFixture, func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
- jsonparser.Get(value, "url")
- nothing()
- }, "person", "gravatar", "avatars")
- }
- }
- func BenchmarkJsonParserDeleteMedium(b *testing.B) {
- fixture := make([]byte, 0, len(mediumFixture))
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- fixture = append(fixture[:0], mediumFixture...)
- fixture = jsonparser.Delete(fixture, "person", "name", "fullName")
- fixture = jsonparser.Delete(fixture, "person", "github", "followers")
- fixture = jsonparser.Delete(fixture, "company")
- nothing()
- }
- }
- func BenchmarkJsonParserEachKeyManualMedium(b *testing.B) {
- paths := [][]string{
- []string{"person", "name", "fullName"},
- []string{"person", "github", "followers"},
- []string{"company"},
- []string{"person", "gravatar", "avatars"},
- }
- for i := 0; i < b.N; i++ {
- jsonparser.EachKey(mediumFixture, func(idx int, value []byte, vt jsonparser.ValueType, err error) {
- switch idx {
- case 0:
- // jsonparser.ParseString(value)
- case 1:
- jsonparser.ParseInt(value)
- case 2:
- // jsonparser.ParseString(value)
- case 3:
- jsonparser.ArrayEach(value, func(avalue []byte, dataType jsonparser.ValueType, offset int, err error) {
- jsonparser.Get(avalue, "url")
- })
- }
- }, paths...)
- }
- }
- func BenchmarkJsonParserEachKeyStructMedium(b *testing.B) {
- paths := [][]string{
- []string{"person", "name", "fullName"},
- []string{"person", "github", "followers"},
- []string{"company"},
- []string{"person", "gravatar", "avatars"},
- }
- for i := 0; i < b.N; i++ {
- data := MediumPayload{
- Person: &CBPerson{
- Name: &CBName{},
- Github: &CBGithub{},
- Gravatar: &CBGravatar{},
- },
- }
- jsonparser.EachKey(mediumFixture, func(idx int, value []byte, vt jsonparser.ValueType, err error) {
- switch idx {
- case 0:
- data.Person.Name.FullName, _ = jsonparser.ParseString(value)
- case 1:
- v, _ := jsonparser.ParseInt(value)
- data.Person.Github.Followers = int(v)
- case 2:
- json.Unmarshal(value, &data.Company) // we don't have a JSON -> map[string]interface{} function yet, so use standard encoding/json here
- case 3:
- var avatars []*CBAvatar
- jsonparser.ArrayEach(value, func(avalue []byte, dataType jsonparser.ValueType, offset int, err error) {
- url, _ := jsonparser.ParseString(avalue)
- avatars = append(avatars, &CBAvatar{Url: url})
- })
- data.Person.Gravatar.Avatars = avatars
- }
- }, paths...)
- }
- }
- func BenchmarkJsonParserObjectEachStructMedium(b *testing.B) {
- nameKey, githubKey, gravatarKey := []byte("name"), []byte("github"), []byte("gravatar")
- errStop := errors.New("stop")
- for i := 0; i < b.N; i++ {
- data := MediumPayload{
- Person: &CBPerson{
- Name: &CBName{},
- Github: &CBGithub{},
- Gravatar: &CBGravatar{},
- },
- }
- missing := 3
- jsonparser.ObjectEach(mediumFixture, func(k, v []byte, vt jsonparser.ValueType, o int) error {
- switch {
- case bytes.Equal(k, nameKey):
- data.Person.Name.FullName, _ = jsonparser.GetString(v, "fullName")
- missing--
- case bytes.Equal(k, githubKey):
- x, _ := jsonparser.GetInt(v, "followers")
- data.Person.Github.Followers = int(x)
- missing--
- case bytes.Equal(k, gravatarKey):
- var avatars []*CBAvatar
- jsonparser.ArrayEach(v, func(avalue []byte, dataType jsonparser.ValueType, offset int, err error) {
- url, _ := jsonparser.ParseString(avalue)
- avatars = append(avatars, &CBAvatar{Url: url})
- }, "avatars")
- data.Person.Gravatar.Avatars = avatars
- missing--
- }
- if missing == 0 {
- return errStop
- } else {
- return nil
- }
- }, "person")
- cv, _, _, _ := jsonparser.Get(mediumFixture, "company")
- json.Unmarshal(cv, &data.Company)
- }
- }
- /*
- encoding/json
- */
- func BenchmarkEncodingJsonStructMedium(b *testing.B) {
- for i := 0; i < b.N; i++ {
- var data MediumPayload
- json.Unmarshal(mediumFixture, &data)
- nothing(data.Person.Name.FullName, data.Person.Github.Followers, data.Company)
- for _, el := range data.Person.Gravatar.Avatars {
- nothing(el.Url)
- }
- }
- }
- func BenchmarkEncodingJsonInterfaceMedium(b *testing.B) {
- for i := 0; i < b.N; i++ {
- var data interface{}
- json.Unmarshal(mediumFixture, &data)
- m := data.(map[string]interface{})
- person := m["person"].(map[string]interface{})
- name := person["name"].(map[string]interface{})
- github := person["github"].(map[string]interface{})
- company := m["company"]
- gravatar := person["gravatar"].(map[string]interface{})
- avatars := gravatar["avatars"].([]interface{})
- nothing(name["fullName"].(string), github["followers"].(float64), company)
- for _, a := range avatars {
- nothing(a.(map[string]interface{})["url"])
- }
- }
- }
- /*
- github.com/Jeffail/gabs
- */
- func BenchmarkGabsMedium(b *testing.B) {
- for i := 0; i < b.N; i++ {
- json, _ := gabs.ParseJSON(mediumFixture)
- person := json.Path("person")
- nothing(
- person.Path("name.fullName").Data().(string),
- person.Path("github.followers").Data().(float64),
- )
- json.Path("company").ChildrenMap()
- arr, _ := person.Path("gravatar.avatars.url").Children()
- for _, el := range arr {
- nothing(el.String())
- }
- }
- }
- /*
- github.com/bitly/go-simplejson
- */
- func BenchmarkGoSimpleJsonMedium(b *testing.B) {
- for i := 0; i < b.N; i++ {
- json, _ := simplejson.NewJson(mediumFixture)
- person := json.Get("person")
- person.Get("name").Get("fullName").String()
- person.Get("github").Get("followers").Float64()
- json.Get("company")
- arr, _ := person.Get("gravatar").Get("avatars").Array()
- for _, el := range arr {
- nothing(el.(map[string]interface{})["url"])
- }
- }
- }
- /*
- github.com/pquerna/ffjson
- */
- func BenchmarkFFJsonMedium(b *testing.B) {
- for i := 0; i < b.N; i++ {
- var data MediumPayload
- ffjson.Unmarshal(mediumFixture, &data)
- nothing(data.Person.Name.FullName, data.Person.Github.Followers, data.Company)
- for _, el := range data.Person.Gravatar.Avatars {
- nothing(el.Url)
- }
- }
- }
- /*
- github.com/bitly/go-simplejson
- */
- func BenchmarkJasonMedium(b *testing.B) {
- for i := 0; i < b.N; i++ {
- json, _ := jason.NewObjectFromBytes(mediumFixture)
- json.GetString("person.name.fullName")
- json.GetFloat64("person.github.followers")
- json.GetObject("company")
- arr, _ := json.GetObjectArray("person.gravatar.avatars")
- for _, el := range arr {
- el.GetString("url")
- }
- nothing()
- }
- }
- /*
- github.com/mreiferson/go-ujson
- */
- func BenchmarkUjsonMedium(b *testing.B) {
- for i := 0; i < b.N; i++ {
- json, _ := ujson.NewFromBytes(mediumFixture)
- person := json.Get("person")
- person.Get("name").Get("fullName").String()
- person.Get("github").Get("followers").Float64()
- json.Get("company").String()
- arr := person.Get("gravatar").Get("avatars").Array()
- for _, el := range arr {
- el.Get("url").String()
- }
- nothing()
- }
- }
- /*
- github.com/a8m/djson
- */
- func BenchmarkDjsonMedium(b *testing.B) {
- for i := 0; i < b.N; i++ {
- m, _ := djson.DecodeObject(mediumFixture)
- person := m["person"].(map[string]interface{})
- name := person["name"].(map[string]interface{})
- github := person["github"].(map[string]interface{})
- company := m["company"]
- gravatar := person["gravatar"].(map[string]interface{})
- avatars := gravatar["avatars"].([]interface{})
- nothing(name["fullName"].(string), github["followers"].(float64), company)
- for _, a := range avatars {
- nothing(a.(map[string]interface{})["url"])
- }
- }
- }
- /*
- github.com/ugorji/go/codec
- */
- func BenchmarkUgirjiMedium(b *testing.B) {
- for i := 0; i < b.N; i++ {
- decoder := codec.NewDecoderBytes(mediumFixture, new(codec.JsonHandle))
- data := new(MediumPayload)
- json.Unmarshal(mediumFixture, &data)
- data.CodecDecodeSelf(decoder)
- nothing(data.Person.Name.FullName, data.Person.Github.Followers, data.Company)
- for _, el := range data.Person.Gravatar.Avatars {
- nothing(el.Url)
- }
- }
- }
- /*
- github.com/mailru/easyjson
- */
- func BenchmarkEasyJsonMedium(b *testing.B) {
- for i := 0; i < b.N; i++ {
- lexer := &jlexer.Lexer{Data: mediumFixture}
- data := new(MediumPayload)
- data.UnmarshalEasyJSON(lexer)
- nothing(data.Person.Name.FullName, data.Person.Github.Followers, data.Company)
- for _, el := range data.Person.Gravatar.Avatars {
- nothing(el.Url)
- }
- }
- }
|