From c37a3c1aac7bf37d832f2a653e141ecde59eff88 Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Sun, 26 Apr 2020 12:03:17 +0900 Subject: [PATCH] Fix benchmark --- README.md | 81 +++- benchmark_test.go | 143 ------- benchmarks/decode_test.go | 225 +++++++++++ benchmarks/encode_test.go | 149 +++++++ benchmarks/go.mod | 10 + benchmarks/go.sum | 181 +++++++++ benchmarks/large_payload.go | 177 ++++++++ benchmarks/large_payload_easyjson.go | 425 ++++++++++++++++++++ benchmarks/medium_payload.go | 316 +++++++++++++++ benchmarks/medium_payload_easyjson.go | 559 ++++++++++++++++++++++++++ benchmarks/small_payload.go | 76 ++++ benchmarks/small_payload_easyjson.go | 186 +++++++++ go.mod | 6 +- go.sum | 177 -------- 14 files changed, 2376 insertions(+), 335 deletions(-) delete mode 100644 benchmark_test.go create mode 100644 benchmarks/decode_test.go create mode 100644 benchmarks/encode_test.go create mode 100644 benchmarks/go.mod create mode 100644 benchmarks/go.sum create mode 100644 benchmarks/large_payload.go create mode 100644 benchmarks/large_payload_easyjson.go create mode 100644 benchmarks/medium_payload.go create mode 100644 benchmarks/medium_payload_easyjson.go create mode 100644 benchmarks/small_payload.go create mode 100644 benchmarks/small_payload_easyjson.go diff --git a/README.md b/README.md index 5e9087d..2856a3e 100644 --- a/README.md +++ b/README.md @@ -9,19 +9,80 @@ WIP # Benchmarks ``` +$ cd benchmarks $ go test -bench . +``` + +## Environment + +``` goos: darwin goarch: amd64 -pkg: github.com/goccy/go-json -Benchmark_Encode_jsoniter-12 5000000 377 ns/op 56 B/op 2 allocs/op -Benchmark_Encode_gojay-12 5000000 273 ns/op 512 B/op 1 allocs/op -Benchmark_Encode_gojson-12 10000000 217 ns/op 48 B/op 1 allocs/op -Benchmark_Decode_jsoniter-12 2000000 856 ns/op 208 B/op 13 allocs/op -Benchmark_Decode_gojay-12 3000000 548 ns/op 256 B/op 2 allocs/op -Benchmark_Decode_gojson-12 3000000 522 ns/op 256 B/op 2 allocs/op -Benchmark_Decode_gojson_noescape-12 3000000 470 ns/op 144 B/op 1 allocs/op -PASS -ok github.com/goccy/go-json 15.120s +``` + +## Decode + +### SmallStruct + +``` +Benchmark_Decode_SmallStruct_EncodingJson-12 1000000 1660 ns/op 280 B/op 3 allocs/op +Benchmark_Decode_SmallStruct_JsonIter-12 1000000 1284 ns/op 316 B/op 12 allocs/op +Benchmark_Decode_SmallStruct_EasyJson-12 2000000 613 ns/op 240 B/op 2 allocs/op +Benchmark_Decode_SmallStruct_GoJay-12 3000000 557 ns/op 256 B/op 2 allocs/op +Benchmark_Decode_SmallStruct_GoJayUnsafe-12 3000000 507 ns/op 112 B/op 1 allocs/op +Benchmark_Decode_SmallStruct_GoJson-12 3000000 512 ns/op 256 B/op 2 allocs/op +Benchmark_Decode_SmallStruct_GoJsonNoEscape-12 3000000 466 ns/op 144 B/op 1 allocs/op +``` + +### MediumStruct + +Benchmark_Decode_MediumStruct_EncodingJson-12 100000 20643 ns/op 384 B/op 10 allocs/op +Benchmark_Decode_MediumStruct_JsonIter-12 200000 11367 ns/op 2985 B/op 81 allocs/op +Benchmark_Decode_MediumStruct_EasyJson-12 200000 6635 ns/op 232 B/op 6 allocs/op +Benchmark_Decode_MediumStruct_GoJay-12 500000 3398 ns/op 2449 B/op 8 allocs/op +Benchmark_Decode_MediumStruct_GoJayUnsafe-12 500000 3067 ns/op 144 B/op 7 allocs/op +``` + +### LargeStruct + +``` +Benchmark_Decode_LargeStruct_EncodingJson-12 5000 288411 ns/op 312 B/op 6 allocs/op +Benchmark_Decode_LargeStruct_JsonIter-12 10000 180028 ns/op 41737 B/op 1137 allocs/op +Benchmark_Decode_LargeStruct_EasyJson-12 10000 105801 ns/op 160 B/op 2 allocs/op +Benchmark_Decode_LargeStruct_GoJay-12 50000 35966 ns/op 31244 B/op 77 allocs/op +Benchmark_Decode_LargeStruct_GoJayUnsafe-12 50000 32536 ns/op 2561 B/op 76 allocs/op +``` + +## Encode + +### SmallStruct + +``` +Benchmark_Encode_SmallStruct_EncodingJson-12 1000000 1665 ns/op 1048 B/op 8 allocs/op +Benchmark_Encode_SmallStruct_JsonIter-12 2000000 737 ns/op 984 B/op 7 allocs/op +Benchmark_Encode_SmallStruct_EasyJson-12 3000000 550 ns/op 944 B/op 6 allocs/op +Benchmark_Encode_SmallStruct_GoJay-12 3000000 421 ns/op 624 B/op 2 allocs/op +Benchmark_Encode_SmallStruct_GoJson-12 5000000 347 ns/op 256 B/op 2 allocs/op +``` + +### MediumStruct + +``` +Benchmark_Encode_MediumStruct_EncodingJson-12 500000 3800 ns/op 1712 B/op 24 allocs/op +Benchmark_Encode_MediumStruct_JsonIter-12 1000000 1438 ns/op 1536 B/op 20 allocs/op +Benchmark_Encode_MediumStruct_EasyJson-12 1000000 1154 ns/op 1320 B/op 19 allocs/op +Benchmark_Encode_MediumStruct_GoJay-12 1000000 1040 ns/op 824 B/op 15 allocs/op +Benchmark_Encode_MediumStruct_GoJson-12 2000000 898 ns/op 632 B/op 15 allocs/op +``` + +### LargeStruct + +``` +Benchmark_Encode_LargeStruct_EncodingJson-12 30000 53287 ns/op 20388 B/op 331 allocs/op +Benchmark_Encode_LargeStruct_JsonIter-12 100000 21251 ns/op 20270 B/op 328 allocs/op +Benchmark_Encode_LargeStruct_EasyJson-12 100000 21303 ns/op 15461 B/op 327 allocs/op +Benchmark_Encode_LargeStruct_GoJay-12 100000 22500 ns/op 28049 B/op 323 allocs/op +Benchmark_Encode_LargeStruct_GoJson-12 100000 17957 ns/op 14697 B/op 319 allocs/op ``` # License diff --git a/benchmark_test.go b/benchmark_test.go deleted file mode 100644 index 3fec607..0000000 --- a/benchmark_test.go +++ /dev/null @@ -1,143 +0,0 @@ -package json_test - -import ( - "testing" - - gojay "github.com/francoispqt/gojay" - gojson "github.com/goccy/go-json" - jsoniter "github.com/json-iterator/go" -) - -type T struct { - A int `json:"a"` - B float64 `json:"b"` - C string `json:"c"` -} - -func (t *T) MarshalJSONObject(enc *gojay.Encoder) { - enc.IntKey("a", t.A) - enc.FloatKey("b", t.B) - enc.StringKey("c", t.C) -} - -func (t *T) IsNil() bool { - return t == nil -} - -func newT() *T { - return &T{A: 1, B: 3.14, C: `hello"world`} -} - -func Benchmark_Encode_jsoniter(b *testing.B) { - v := newT() - var json = jsoniter.ConfigCompatibleWithStandardLibrary - b.ReportAllocs() - for i := 0; i < b.N; i++ { - if _, err := json.Marshal(v); err != nil { - b.Fatal(err) - } - } -} - -func Benchmark_Encode_gojay(b *testing.B) { - v := newT() - b.ReportAllocs() - for i := 0; i < b.N; i++ { - if _, err := gojay.MarshalJSONObject(v); err != nil { - b.Fatal(err) - } - } -} - -func Benchmark_Encode_gojson(b *testing.B) { - v := newT() - b.ReportAllocs() - for i := 0; i < b.N; i++ { - if _, err := gojson.Marshal(v); err != nil { - b.Fatal(err) - } - } -} - -var fixture = []byte(`{"st": 1,"sid": 486,"tt": "active","gr": 0,"uuid": "de305d54-75b4-431b-adb2-eb6b9e546014","ip": "127.0.0.1","ua": "user_agent","tz": -6,"v": 1}`) - -type SmallPayload struct { - St int - Sid int - Tt string - Gr int - Uuid string - Ip string - Ua string - Tz int - V int -} - -func (t *SmallPayload) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { - switch key { - case "st": - return dec.AddInt(&t.St) - case "sid": - return dec.AddInt(&t.Sid) - case "gr": - return dec.AddInt(&t.Gr) - case "tz": - return dec.AddInt(&t.Tz) - case "v": - return dec.AddInt(&t.V) - case "tt": - return dec.AddString(&t.Tt) - case "uuid": - return dec.AddString(&t.Uuid) - case "ip": - return dec.AddString(&t.Ip) - case "ua": - return dec.AddString(&t.Ua) - } - return nil -} - -func (t *SmallPayload) NKeys() int { - return 9 -} - -func Benchmark_Decode_jsoniter(b *testing.B) { - var json = jsoniter.ConfigCompatibleWithStandardLibrary - b.ReportAllocs() - for i := 0; i < b.N; i++ { - var v SmallPayload - if err := json.Unmarshal(fixture, &v); err != nil { - b.Fatal(err) - } - } -} - -func Benchmark_Decode_gojay(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - var v SmallPayload - if err := gojay.UnmarshalJSONObject(fixture, &v); err != nil { - b.Fatal(err) - } - } -} - -func Benchmark_Decode_gojson(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - var v SmallPayload - if err := gojson.Unmarshal(fixture, &v); err != nil { - b.Fatal(err) - } - } -} - -func Benchmark_Decode_gojson_noescape(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - var v SmallPayload - if err := gojson.UnmarshalNoEscape(fixture, &v); err != nil { - b.Fatal(err) - } - } -} diff --git a/benchmarks/decode_test.go b/benchmarks/decode_test.go new file mode 100644 index 0000000..f3d2ee7 --- /dev/null +++ b/benchmarks/decode_test.go @@ -0,0 +1,225 @@ +package benchmark + +import ( + "encoding/json" + "testing" + + gojay "github.com/francoispqt/gojay" + gojson "github.com/goccy/go-json" + jsoniter "github.com/json-iterator/go" + easyjson "github.com/mailru/easyjson" +) + +func Benchmark_Decode_SmallStruct_EncodingJson(b *testing.B) { + b.ReportAllocs() + for n := 0; n < b.N; n++ { + result := SmallPayload{} + if err := json.Unmarshal(SmallFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Decode_SmallStruct_JsonIter(b *testing.B) { + b.ReportAllocs() + for n := 0; n < b.N; n++ { + result := SmallPayload{} + if err := jsoniter.Unmarshal(SmallFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Decode_SmallStruct_EasyJson(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + result := SmallPayload{} + if err := easyjson.Unmarshal(SmallFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Decode_SmallStruct_GoJay(b *testing.B) { + b.ReportAllocs() + for n := 0; n < b.N; n++ { + result := SmallPayload{} + if err := gojay.UnmarshalJSONObject(SmallFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Decode_SmallStruct_GoJayUnsafe(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + result := SmallPayload{} + if err := gojay.Unsafe.UnmarshalJSONObject(SmallFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Decode_SmallStruct_GoJson(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + result := SmallPayload{} + if err := gojson.Unmarshal(SmallFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Decode_SmallStruct_GoJsonNoEscape(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + result := SmallPayload{} + if err := gojson.UnmarshalNoEscape(SmallFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Decode_MediumStruct_EncodingJson(b *testing.B) { + b.ReportAllocs() + for n := 0; n < b.N; n++ { + result := MediumPayload{} + if err := json.Unmarshal(MediumFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Decode_MediumStruct_JsonIter(b *testing.B) { + b.ReportAllocs() + for n := 0; n < b.N; n++ { + result := MediumPayload{} + if err := jsoniter.Unmarshal(MediumFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Decode_MediumStruct_EasyJson(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + result := MediumPayload{} + if err := easyjson.Unmarshal(MediumFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Decode_MediumStruct_GoJay(b *testing.B) { + b.ReportAllocs() + for n := 0; n < b.N; n++ { + result := MediumPayload{} + if err := gojay.UnmarshalJSONObject(MediumFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Decode_MediumStruct_GoJayUnsafe(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + result := MediumPayload{} + if err := gojay.Unsafe.UnmarshalJSONObject(MediumFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +/* +func Benchmark_Decode_MediumStruct_GoJson(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + result := MediumPayload{} + if err := gojson.Unmarshal(MediumFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Decode_MediumStruct_GoJsonNoEscape(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + result := MediumPayload{} + if err := gojson.UnmarshalNoEscape(MediumFixture, &result); err != nil { + b.Fatal(err) + } + } +} +*/ + +func Benchmark_Decode_LargeStruct_EncodingJson(b *testing.B) { + b.ReportAllocs() + for n := 0; n < b.N; n++ { + result := LargePayload{} + if err := json.Unmarshal(LargeFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Decode_LargeStruct_JsonIter(b *testing.B) { + b.ReportAllocs() + for n := 0; n < b.N; n++ { + result := LargePayload{} + if err := jsoniter.Unmarshal(LargeFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Decode_LargeStruct_EasyJson(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + result := LargePayload{} + if err := easyjson.Unmarshal(LargeFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Decode_LargeStruct_GoJay(b *testing.B) { + b.ReportAllocs() + for n := 0; n < b.N; n++ { + result := LargePayload{} + if err := gojay.UnmarshalJSONObject(LargeFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Decode_LargeStruct_GoJayUnsafe(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + result := LargePayload{} + if err := gojay.Unsafe.UnmarshalJSONObject(LargeFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +/* +func Benchmark_Decode_LargeStruct_GoJson(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + result := LargePayload{} + if err := gojson.Unmarshal(LargeFixture, &result); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Decode_LargeStruct_GoJsonNoEscape(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + result := LargePayload{} + if err := gojson.UnmarshalNoEscape(LargeFixture, &result); err != nil { + b.Fatal(err) + } + } +} +*/ diff --git a/benchmarks/encode_test.go b/benchmarks/encode_test.go new file mode 100644 index 0000000..50e414e --- /dev/null +++ b/benchmarks/encode_test.go @@ -0,0 +1,149 @@ +package benchmark + +import ( + "encoding/json" + "testing" + + gojay "github.com/francoispqt/gojay" + gojson "github.com/goccy/go-json" + jsoniter "github.com/json-iterator/go" + easyjson "github.com/mailru/easyjson" +) + +func Benchmark_Encode_SmallStruct_EncodingJson(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if _, err := json.Marshal(NewSmallPayload()); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Encode_SmallStruct_JsonIter(b *testing.B) { + var json = jsoniter.ConfigCompatibleWithStandardLibrary + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if _, err := json.Marshal(NewSmallPayload()); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Encode_SmallStruct_EasyJson(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if _, err := easyjson.Marshal(NewSmallPayload()); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Encode_SmallStruct_GoJay(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if _, err := gojay.MarshalJSONObject(NewSmallPayload()); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Encode_SmallStruct_GoJson(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if _, err := gojson.Marshal(NewSmallPayload()); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Encode_MediumStruct_EncodingJson(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if _, err := json.Marshal(NewMediumPayload()); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Encode_MediumStruct_JsonIter(b *testing.B) { + var json = jsoniter.ConfigCompatibleWithStandardLibrary + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if _, err := json.Marshal(NewMediumPayload()); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Encode_MediumStruct_EasyJson(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if _, err := easyjson.Marshal(NewMediumPayload()); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Encode_MediumStruct_GoJay(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if _, err := gojay.MarshalJSONObject(NewMediumPayload()); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Encode_MediumStruct_GoJson(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if _, err := gojson.Marshal(NewMediumPayload()); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Encode_LargeStruct_EncodingJson(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if _, err := json.Marshal(NewLargePayload()); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Encode_LargeStruct_JsonIter(b *testing.B) { + var json = jsoniter.ConfigCompatibleWithStandardLibrary + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if _, err := json.Marshal(NewLargePayload()); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Encode_LargeStruct_EasyJson(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if _, err := easyjson.Marshal(NewLargePayload()); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Encode_LargeStruct_GoJay(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if _, err := gojay.MarshalJSONObject(NewLargePayload()); err != nil { + b.Fatal(err) + } + } +} + +func Benchmark_Encode_LargeStruct_GoJson(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if _, err := gojson.Marshal(NewLargePayload()); err != nil { + b.Fatal(err) + } + } +} diff --git a/benchmarks/go.mod b/benchmarks/go.mod new file mode 100644 index 0000000..7929db3 --- /dev/null +++ b/benchmarks/go.mod @@ -0,0 +1,10 @@ +module benchmark + +go 1.12 + +require ( + github.com/francoispqt/gojay v1.2.13 + github.com/goccy/go-json v0.0.0-20200425134937-b2f2a20f6518 + github.com/json-iterator/go v1.1.9 + github.com/mailru/easyjson v0.7.1 +) diff --git a/benchmarks/go.sum b/benchmarks/go.sum new file mode 100644 index 0000000..695a5a5 --- /dev/null +++ b/benchmarks/go.sum @@ -0,0 +1,181 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= +dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= +dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= +dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= +dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= +git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= +github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= +github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/goccy/go-json v0.0.0-20200425134937-b2f2a20f6518 h1:Im9WLti1rM0Lu7yfI7Q4qUa63ACa8MpcWsKsP/s1scI= +github.com/goccy/go-json v0.0.0-20200425134937-b2f2a20f6518/go.mod h1:h37TlF6fMJkCKBvuOxM3yCc3CnzMOUL3Ya+zO4ERYXQ= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.1 h1:mdxE1MF9o53iCb2Ghj1VfWvh7ZOwHpnVG/xwXrV90U8= +github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= +github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= +github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= +github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= +github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= +github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= +github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= +github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= +github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= +github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= +github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= +github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= +github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= +github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= +github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= +github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= +github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= +github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= +github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= +github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= +github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= +go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= +go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= +golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= +google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= +sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/benchmarks/large_payload.go b/benchmarks/large_payload.go new file mode 100644 index 0000000..4fa2648 --- /dev/null +++ b/benchmarks/large_payload.go @@ -0,0 +1,177 @@ +package benchmark + +import ( + "strconv" + + "github.com/francoispqt/gojay" +) + +type DSUser struct { + Username string +} + +func (m *DSUser) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { + switch key { + case "username": + return dec.AddString(&m.Username) + } + return nil +} +func (m *DSUser) NKeys() int { + return 1 +} +func (m *DSUser) IsNil() bool { + return m == nil +} +func (m *DSUser) MarshalJSONObject(enc *gojay.Encoder) { + enc.AddStringKey("username", m.Username) +} + +type DSTopic struct { + Id int + Slug string +} + +func (m *DSTopic) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { + switch key { + case "id": + return dec.AddInt(&m.Id) + case "slug": + return dec.AddString(&m.Slug) + } + return nil +} +func (m *DSTopic) NKeys() int { + return 2 +} +func (m *DSTopic) IsNil() bool { + return m == nil +} +func (m *DSTopic) MarshalJSONObject(enc *gojay.Encoder) { + enc.AddIntKey("id", m.Id) + enc.AddStringKey("slug", m.Slug) +} + +type DSTopics []*DSTopic + +func (t *DSTopics) UnmarshalJSONArray(dec *gojay.Decoder) error { + dsTopic := &DSTopic{} + *t = append(*t, dsTopic) + return dec.AddObject(dsTopic) +} + +func (m *DSTopics) MarshalJSONArray(enc *gojay.Encoder) { + for _, e := range *m { + enc.AddObject(e) + } +} +func (m *DSTopics) IsNil() bool { + return m == nil +} + +type DSTopicsList struct { + Topics DSTopics + MoreTopicsUrl string +} + +func (m *DSTopicsList) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { + switch key { + case "topics": + m.Topics = DSTopics{} + return dec.AddArray(&m.Topics) + case "more_topics_url": + return dec.AddString(&m.MoreTopicsUrl) + } + return nil +} +func (m *DSTopicsList) NKeys() int { + return 2 +} + +func (m *DSTopicsList) IsNil() bool { + return m == nil +} + +func (m *DSTopicsList) MarshalJSONObject(enc *gojay.Encoder) { + enc.AddArrayKey("users", &m.Topics) + enc.AddStringKey("more_topics_url", m.MoreTopicsUrl) +} + +type DSUsers []*DSUser + +func (t *DSUsers) UnmarshalJSONArray(dec *gojay.Decoder) error { + dsUser := DSUser{} + *t = append(*t, &dsUser) + return dec.AddObject(&dsUser) +} + +func (m *DSUsers) MarshalJSONArray(enc *gojay.Encoder) { + for _, e := range *m { + enc.AddObject(e) + } +} +func (m *DSUsers) IsNil() bool { + return m == nil +} + +type LargePayload struct { + Users DSUsers + Topics *DSTopicsList +} + +func (m *LargePayload) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { + switch key { + case "users": + return dec.AddArray(&m.Users) + case "topics": + m.Topics = &DSTopicsList{} + return dec.AddObject(m.Topics) + } + return nil +} + +func (m *LargePayload) NKeys() int { + return 2 +} + +//easyjson:json +func (m *LargePayload) MarshalJSONObject(enc *gojay.Encoder) { + enc.AddArrayKey("users", &m.Users) + enc.AddObjectKey("topics", m.Topics) +} + +func (m *LargePayload) IsNil() bool { + return m == nil +} + +var LargeFixture = []byte(` + {"users":[{"id":-1,"username":"system","avatar_template":"/user_avatar/discourse.metabase.com/system/{size}/6_1.png"},{"id":89,"username":"zergot","avatar_template":"https://avatars.discourse.org/v2/letter/z/0ea827/{size}.png"},{"id":1,"username":"sameer","avatar_template":"https://avatars.discourse.org/v2/letter/s/bbce88/{size}.png"},{"id":84,"username":"HenryMirror","avatar_template":"https://avatars.discourse.org/v2/letter/h/ecd19e/{size}.png"},{"id":73,"username":"fimp","avatar_template":"https://avatars.discourse.org/v2/letter/f/ee59a6/{size}.png"},{"id":14,"username":"agilliland","avatar_template":"/user_avatar/discourse.metabase.com/agilliland/{size}/26_1.png"},{"id":87,"username":"amir","avatar_template":"https://avatars.discourse.org/v2/letter/a/c37758/{size}.png"},{"id":82,"username":"waseem","avatar_template":"https://avatars.discourse.org/v2/letter/w/9dc877/{size}.png"},{"id":78,"username":"tovenaar","avatar_template":"https://avatars.discourse.org/v2/letter/t/9de0a6/{size}.png"},{"id":74,"username":"Ben","avatar_template":"https://avatars.discourse.org/v2/letter/b/df788c/{size}.png"},{"id":71,"username":"MarkLaFay","avatar_template":"https://avatars.discourse.org/v2/letter/m/3bc359/{size}.png"},{"id":72,"username":"camsaul","avatar_template":"/user_avatar/discourse.metabase.com/camsaul/{size}/70_1.png"},{"id":53,"username":"mhjb","avatar_template":"/user_avatar/discourse.metabase.com/mhjb/{size}/54_1.png"},{"id":58,"username":"jbwiv","avatar_template":"https://avatars.discourse.org/v2/letter/j/6bbea6/{size}.png"},{"id":70,"username":"Maggs","avatar_template":"https://avatars.discourse.org/v2/letter/m/bbce88/{size}.png"},{"id":69,"username":"andrefaria","avatar_template":"/user_avatar/discourse.metabase.com/andrefaria/{size}/65_1.png"},{"id":60,"username":"bencarter78","avatar_template":"/user_avatar/discourse.metabase.com/bencarter78/{size}/59_1.png"},{"id":55,"username":"vikram","avatar_template":"https://avatars.discourse.org/v2/letter/v/e47774/{size}.png"},{"id":68,"username":"edchan77","avatar_template":"/user_avatar/discourse.metabase.com/edchan77/{size}/66_1.png"},{"id":9,"username":"karthikd","avatar_template":"https://avatars.discourse.org/v2/letter/k/cab0a1/{size}.png"},{"id":23,"username":"arthurz","avatar_template":"/user_avatar/discourse.metabase.com/arthurz/{size}/32_1.png"},{"id":3,"username":"tom","avatar_template":"/user_avatar/discourse.metabase.com/tom/{size}/21_1.png"},{"id":50,"username":"LeoNogueira","avatar_template":"/user_avatar/discourse.metabase.com/leonogueira/{size}/52_1.png"},{"id":66,"username":"ss06vi","avatar_template":"https://avatars.discourse.org/v2/letter/s/3ab097/{size}.png"},{"id":34,"username":"mattcollins","avatar_template":"/user_avatar/discourse.metabase.com/mattcollins/{size}/41_1.png"},{"id":51,"username":"krmmalik","avatar_template":"/user_avatar/discourse.metabase.com/krmmalik/{size}/53_1.png"},{"id":46,"username":"odysseas","avatar_template":"https://avatars.discourse.org/v2/letter/o/5f8ce5/{size}.png"},{"id":5,"username":"jonthewayne","avatar_template":"/user_avatar/discourse.metabase.com/jonthewayne/{size}/18_1.png"},{"id":11,"username":"anandiyer","avatar_template":"/user_avatar/discourse.metabase.com/anandiyer/{size}/23_1.png"},{"id":25,"username":"alnorth","avatar_template":"/user_avatar/discourse.metabase.com/alnorth/{size}/34_1.png"},{"id":52,"username":"j_at_svg","avatar_template":"https://avatars.discourse.org/v2/letter/j/96bed5/{size}.png"},{"id":42,"username":"styts","avatar_template":"/user_avatar/discourse.metabase.com/styts/{size}/47_1.png"}],"topics":{"can_create_topic":false,"more_topics_url":"/c/uncategorized/l/latest?page=1","draft":null,"draft_key":"new_topic","draft_sequence":null,"per_page":30,"topics":[{"id":8,"title":"Welcome to Metabase's Discussion Forum","fancy_title":"Welcome to Metabase’s Discussion Forum","slug":"welcome-to-metabases-discussion-forum","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":"/images/welcome/discourse-edit-post-animated.gif","created_at":"2015-10-17T00:14:49.526Z","last_posted_at":"2015-10-17T00:14:49.557Z","bumped":true,"bumped_at":"2015-10-21T02:32:22.486Z","unseen":false,"pinned":true,"unpinned":null,"excerpt":"Welcome to Metabase's discussion forum. This is a place to get help on installation, setting up as well as sharing tips and tricks.","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":197,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"system","category_id":1,"pinned_globally":true,"posters":[{"extras":"latest single","description":"Original Poster, Most Recent Poster","user_id":-1}]},{"id":169,"title":"Formatting Dates","fancy_title":"Formatting Dates","slug":"formatting-dates","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2016-01-14T06:30:45.311Z","last_posted_at":"2016-01-14T06:30:45.397Z","bumped":true,"bumped_at":"2016-01-14T06:30:45.397Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":11,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"zergot","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest single","description":"Original Poster, Most Recent Poster","user_id":89}]},{"id":168,"title":"Setting for google api key","fancy_title":"Setting for google api key","slug":"setting-for-google-api-key","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2016-01-13T17:14:31.799Z","last_posted_at":"2016-01-14T06:24:03.421Z","bumped":true,"bumped_at":"2016-01-14T06:24:03.421Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":16,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"zergot","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest single","description":"Original Poster, Most Recent Poster","user_id":89}]},{"id":167,"title":"Cannot see non-US timezones on the admin","fancy_title":"Cannot see non-US timezones on the admin","slug":"cannot-see-non-us-timezones-on-the-admin","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2016-01-13T17:07:36.764Z","last_posted_at":"2016-01-13T17:07:36.831Z","bumped":true,"bumped_at":"2016-01-13T17:07:36.831Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":11,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"zergot","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest single","description":"Original Poster, Most Recent Poster","user_id":89}]},{"id":164,"title":"External (Metabase level) linkages in data schema","fancy_title":"External (Metabase level) linkages in data schema","slug":"external-metabase-level-linkages-in-data-schema","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":null,"created_at":"2016-01-11T13:51:02.286Z","last_posted_at":"2016-01-12T11:06:37.259Z","bumped":true,"bumped_at":"2016-01-12T11:06:37.259Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":32,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"zergot","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":89},{"extras":null,"description":"Frequent Poster","user_id":1}]},{"id":155,"title":"Query working on \"Questions\" but not in \"Pulses\"","fancy_title":"Query working on “Questions” but not in “Pulses”","slug":"query-working-on-questions-but-not-in-pulses","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2016-01-01T14:06:10.083Z","last_posted_at":"2016-01-08T22:37:51.772Z","bumped":true,"bumped_at":"2016-01-08T22:37:51.772Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":72,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"agilliland","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":84},{"extras":null,"description":"Frequent Poster","user_id":73},{"extras":"latest","description":"Most Recent Poster","user_id":14}]},{"id":161,"title":"Pulses posted to Slack don't show question output","fancy_title":"Pulses posted to Slack don’t show question output","slug":"pulses-posted-to-slack-dont-show-question-output","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":"/uploads/default/original/1X/9d2806517bf3598b10be135b2c58923b47ba23e7.png","created_at":"2016-01-08T22:09:58.205Z","last_posted_at":"2016-01-08T22:28:44.685Z","bumped":true,"bumped_at":"2016-01-08T22:28:44.685Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":34,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":87},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":152,"title":"Should we build Kafka connecter or Kafka plugin","fancy_title":"Should we build Kafka connecter or Kafka plugin","slug":"should-we-build-kafka-connecter-or-kafka-plugin","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":null,"created_at":"2015-12-28T20:37:23.501Z","last_posted_at":"2015-12-31T18:16:45.477Z","bumped":true,"bumped_at":"2015-12-31T18:16:45.477Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":84,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":82},{"extras":"latest","description":"Most Recent Poster, Frequent Poster","user_id":1}]},{"id":147,"title":"Change X and Y on graph","fancy_title":"Change X and Y on graph","slug":"change-x-and-y-on-graph","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2015-12-21T17:52:46.581Z","last_posted_at":"2015-12-21T17:52:46.684Z","bumped":true,"bumped_at":"2015-12-21T18:19:13.003Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":68,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"tovenaar","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest single","description":"Original Poster, Most Recent Poster","user_id":78}]},{"id":142,"title":"Issues sending mail via office365 relay","fancy_title":"Issues sending mail via office365 relay","slug":"issues-sending-mail-via-office365-relay","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":null,"created_at":"2015-12-16T10:38:47.315Z","last_posted_at":"2015-12-21T09:26:27.167Z","bumped":true,"bumped_at":"2015-12-21T09:26:27.167Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":122,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"Ben","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":74},{"extras":null,"description":"Frequent Poster","user_id":1}]},{"id":137,"title":"I see triplicates of my mongoDB collections","fancy_title":"I see triplicates of my mongoDB collections","slug":"i-see-triplicates-of-my-mongodb-collections","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2015-12-14T13:33:03.426Z","last_posted_at":"2015-12-17T18:40:05.487Z","bumped":true,"bumped_at":"2015-12-17T18:40:05.487Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":97,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"MarkLaFay","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":71},{"extras":null,"description":"Frequent Poster","user_id":14}]},{"id":140,"title":"Google Analytics plugin","fancy_title":"Google Analytics plugin","slug":"google-analytics-plugin","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2015-12-15T13:00:55.644Z","last_posted_at":"2015-12-15T13:00:55.705Z","bumped":true,"bumped_at":"2015-12-15T13:00:55.705Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":105,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"fimp","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest single","description":"Original Poster, Most Recent Poster","user_id":73}]},{"id":138,"title":"With-mongo-connection failed: bad connection details:","fancy_title":"With-mongo-connection failed: bad connection details:","slug":"with-mongo-connection-failed-bad-connection-details","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2015-12-14T17:28:11.041Z","last_posted_at":"2015-12-14T17:28:11.111Z","bumped":true,"bumped_at":"2015-12-14T17:28:11.111Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":56,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"MarkLaFay","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest single","description":"Original Poster, Most Recent Poster","user_id":71}]},{"id":133,"title":"\"We couldn't understand your question.\" when I query mongoDB","fancy_title":"“We couldn’t understand your question.” when I query mongoDB","slug":"we-couldnt-understand-your-question-when-i-query-mongodb","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2015-12-11T17:38:30.576Z","last_posted_at":"2015-12-14T13:31:26.395Z","bumped":true,"bumped_at":"2015-12-14T13:31:26.395Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":107,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"MarkLaFay","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":71},{"extras":null,"description":"Frequent Poster","user_id":72}]},{"id":129,"title":"My bar charts are all thin","fancy_title":"My bar charts are all thin","slug":"my-bar-charts-are-all-thin","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":"/uploads/default/original/1X/41bcf3b2a00dc7cfaff01cb3165d35d32a85bf1d.png","created_at":"2015-12-09T22:09:56.394Z","last_posted_at":"2015-12-11T19:00:45.289Z","bumped":true,"bumped_at":"2015-12-11T19:00:45.289Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":116,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"mhjb","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":53},{"extras":null,"description":"Frequent Poster","user_id":1}]},{"id":106,"title":"What is the expected return order of columns for graphing results when using raw SQL?","fancy_title":"What is the expected return order of columns for graphing results when using raw SQL?","slug":"what-is-the-expected-return-order-of-columns-for-graphing-results-when-using-raw-sql","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2015-11-24T19:07:14.561Z","last_posted_at":"2015-12-11T17:04:14.149Z","bumped":true,"bumped_at":"2015-12-11T17:04:14.149Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":153,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"jbwiv","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":58},{"extras":null,"description":"Frequent Poster","user_id":14}]},{"id":131,"title":"Set site url from admin panel","fancy_title":"Set site url from admin panel","slug":"set-site-url-from-admin-panel","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2015-12-10T06:22:46.042Z","last_posted_at":"2015-12-10T19:12:57.449Z","bumped":true,"bumped_at":"2015-12-10T19:12:57.449Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":77,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":70},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":127,"title":"Internationalization (i18n)","fancy_title":"Internationalization (i18n)","slug":"internationalization-i18n","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2015-12-08T16:55:37.397Z","last_posted_at":"2015-12-09T16:49:55.816Z","bumped":true,"bumped_at":"2015-12-09T16:49:55.816Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":85,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"agilliland","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":69},{"extras":"latest","description":"Most Recent Poster","user_id":14}]},{"id":109,"title":"Returning raw data with no filters always returns We couldn't understand your question","fancy_title":"Returning raw data with no filters always returns We couldn’t understand your question","slug":"returning-raw-data-with-no-filters-always-returns-we-couldnt-understand-your-question","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2015-11-25T21:35:01.315Z","last_posted_at":"2015-12-09T10:26:12.255Z","bumped":true,"bumped_at":"2015-12-09T10:26:12.255Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":133,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"bencarter78","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":60},{"extras":null,"description":"Frequent Poster","user_id":14}]},{"id":103,"title":"Support for Cassandra?","fancy_title":"Support for Cassandra?","slug":"support-for-cassandra","posts_count":5,"reply_count":1,"highest_post_number":5,"image_url":null,"created_at":"2015-11-20T06:45:31.741Z","last_posted_at":"2015-12-09T03:18:51.274Z","bumped":true,"bumped_at":"2015-12-09T03:18:51.274Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":169,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"vikram","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":55},{"extras":null,"description":"Frequent Poster","user_id":1}]},{"id":128,"title":"Mongo query with Date breaks [solved: Mongo 3.0 required]","fancy_title":"Mongo query with Date breaks [solved: Mongo 3.0 required]","slug":"mongo-query-with-date-breaks-solved-mongo-3-0-required","posts_count":5,"reply_count":0,"highest_post_number":5,"image_url":null,"created_at":"2015-12-08T18:30:56.562Z","last_posted_at":"2015-12-08T21:03:02.421Z","bumped":true,"bumped_at":"2015-12-08T21:03:02.421Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":102,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"edchan77","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":68},{"extras":null,"description":"Frequent Poster","user_id":1}]},{"id":23,"title":"Can this connect to MS SQL Server?","fancy_title":"Can this connect to MS SQL Server?","slug":"can-this-connect-to-ms-sql-server","posts_count":7,"reply_count":1,"highest_post_number":7,"image_url":null,"created_at":"2015-10-21T18:52:37.987Z","last_posted_at":"2015-12-07T17:41:51.609Z","bumped":true,"bumped_at":"2015-12-07T17:41:51.609Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":367,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":9},{"extras":null,"description":"Frequent Poster","user_id":23},{"extras":null,"description":"Frequent Poster","user_id":3},{"extras":null,"description":"Frequent Poster","user_id":50},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":121,"title":"Cannot restart metabase in docker","fancy_title":"Cannot restart metabase in docker","slug":"cannot-restart-metabase-in-docker","posts_count":5,"reply_count":1,"highest_post_number":5,"image_url":null,"created_at":"2015-12-04T21:28:58.137Z","last_posted_at":"2015-12-04T23:02:00.488Z","bumped":true,"bumped_at":"2015-12-04T23:02:00.488Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":96,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":66},{"extras":"latest","description":"Most Recent Poster, Frequent Poster","user_id":1}]},{"id":85,"title":"Edit Max Rows Count","fancy_title":"Edit Max Rows Count","slug":"edit-max-rows-count","posts_count":4,"reply_count":2,"highest_post_number":4,"image_url":null,"created_at":"2015-11-11T23:46:52.917Z","last_posted_at":"2015-11-24T01:01:14.569Z","bumped":true,"bumped_at":"2015-11-24T01:01:14.569Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":169,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":34},{"extras":"latest","description":"Most Recent Poster, Frequent Poster","user_id":1}]},{"id":96,"title":"Creating charts by querying more than one table at a time","fancy_title":"Creating charts by querying more than one table at a time","slug":"creating-charts-by-querying-more-than-one-table-at-a-time","posts_count":6,"reply_count":4,"highest_post_number":6,"image_url":null,"created_at":"2015-11-17T11:20:18.442Z","last_posted_at":"2015-11-21T02:12:25.995Z","bumped":true,"bumped_at":"2015-11-21T02:12:25.995Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":217,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":51},{"extras":"latest","description":"Most Recent Poster, Frequent Poster","user_id":1}]},{"id":90,"title":"Trying to add RDS postgresql as the database fails silently","fancy_title":"Trying to add RDS postgresql as the database fails silently","slug":"trying-to-add-rds-postgresql-as-the-database-fails-silently","posts_count":4,"reply_count":2,"highest_post_number":4,"image_url":null,"created_at":"2015-11-14T23:45:02.967Z","last_posted_at":"2015-11-21T01:08:45.915Z","bumped":true,"bumped_at":"2015-11-21T01:08:45.915Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":162,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":46},{"extras":"latest","description":"Most Recent Poster, Frequent Poster","user_id":1}]},{"id":17,"title":"Deploy to Heroku isn't working","fancy_title":"Deploy to Heroku isn’t working","slug":"deploy-to-heroku-isnt-working","posts_count":9,"reply_count":3,"highest_post_number":9,"image_url":null,"created_at":"2015-10-21T16:42:03.096Z","last_posted_at":"2015-11-20T18:34:14.044Z","bumped":true,"bumped_at":"2015-11-20T18:34:14.044Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":332,"like_count":2,"has_summary":false,"archetype":"regular","last_poster_username":"agilliland","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":5},{"extras":null,"description":"Frequent Poster","user_id":3},{"extras":null,"description":"Frequent Poster","user_id":11},{"extras":null,"description":"Frequent Poster","user_id":25},{"extras":"latest","description":"Most Recent Poster","user_id":14}]},{"id":100,"title":"Can I use DATEPART() in SQL queries?","fancy_title":"Can I use DATEPART() in SQL queries?","slug":"can-i-use-datepart-in-sql-queries","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2015-11-17T23:15:58.033Z","last_posted_at":"2015-11-18T00:19:48.763Z","bumped":true,"bumped_at":"2015-11-18T00:19:48.763Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":112,"like_count":1,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":53},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":98,"title":"Feature Request: LDAP Authentication","fancy_title":"Feature Request: LDAP Authentication","slug":"feature-request-ldap-authentication","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2015-11-17T17:22:44.484Z","last_posted_at":"2015-11-17T17:22:44.577Z","bumped":true,"bumped_at":"2015-11-17T17:22:44.577Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":97,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"j_at_svg","category_id":1,"pinned_globally":false,"posters":[{"extras":"latest single","description":"Original Poster, Most Recent Poster","user_id":52}]},{"id":87,"title":"Migrating from internal H2 to Postgres","fancy_title":"Migrating from internal H2 to Postgres","slug":"migrating-from-internal-h2-to-postgres","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2015-11-12T14:36:06.745Z","last_posted_at":"2015-11-12T18:05:10.796Z","bumped":true,"bumped_at":"2015-11-12T18:05:10.796Z","unseen":false,"pinned":false,"unpinned":null,"visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"views":111,"like_count":0,"has_summary":false,"archetype":"regular","last_poster_username":"sameer","category_id":1,"pinned_globally":false,"posters":[{"extras":null,"description":"Original Poster","user_id":42},{"extras":"latest","description":"Most Recent Poster","user_id":1}]}]}} +`) + +func NewLargePayload() *LargePayload { + dsUsers := DSUsers{} + dsTopics := DSTopics{} + for i := 0; i < 100; i++ { + str := "test" + strconv.Itoa(i) + dsUsers = append( + dsUsers, + &DSUser{ + Username: str, + }, + ) + dsTopics = append( + dsTopics, + &DSTopic{ + Id: i, + Slug: str, + }, + ) + } + return &LargePayload{ + Users: dsUsers, + Topics: &DSTopicsList{ + Topics: dsTopics, + MoreTopicsUrl: "http://test.com", + }, + } +} diff --git a/benchmarks/large_payload_easyjson.go b/benchmarks/large_payload_easyjson.go new file mode 100644 index 0000000..ec5cb0d --- /dev/null +++ b/benchmarks/large_payload_easyjson.go @@ -0,0 +1,425 @@ +// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. +package benchmark + +import ( + json "encoding/json" + + easyjson "github.com/mailru/easyjson" + jlexer "github.com/mailru/easyjson/jlexer" + jwriter "github.com/mailru/easyjson/jwriter" +) + +// suppress unused package warning +var ( + _ *json.RawMessage + _ *jlexer.Lexer + _ *jwriter.Writer + _ easyjson.Marshaler +) + +func easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks(in *jlexer.Lexer, out *LargePayload) { + 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 "Users": + if in.IsNull() { + in.Skip() + out.Users = nil + } else { + in.Delim('[') + if out.Users == nil { + if !in.IsDelim(']') { + out.Users = make(DSUsers, 0, 8) + } else { + out.Users = DSUsers{} + } + } else { + out.Users = (out.Users)[:0] + } + for !in.IsDelim(']') { + var v1 *DSUser + if in.IsNull() { + in.Skip() + v1 = nil + } else { + if v1 == nil { + v1 = new(DSUser) + } + (*v1).UnmarshalEasyJSON(in) + } + out.Users = append(out.Users, v1) + in.WantComma() + } + in.Delim(']') + } + case "Topics": + if in.IsNull() { + in.Skip() + out.Topics = nil + } else { + if out.Topics == nil { + out.Topics = new(DSTopicsList) + } + (*out.Topics).UnmarshalEasyJSON(in) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks(out *jwriter.Writer, in LargePayload) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"Users\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + if in.Users == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { + out.RawString("null") + } else { + out.RawByte('[') + for v2, v3 := range in.Users { + if v2 > 0 { + out.RawByte(',') + } + if v3 == nil { + out.RawString("null") + } else { + (*v3).MarshalEasyJSON(out) + } + } + out.RawByte(']') + } + } + { + const prefix string = ",\"Topics\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + if in.Topics == nil { + out.RawString("null") + } else { + (*in.Topics).MarshalEasyJSON(out) + } + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v LargePayload) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v LargePayload) MarshalEasyJSON(w *jwriter.Writer) { + easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *LargePayload) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *LargePayload) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks(l, v) +} +func easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks1(in *jlexer.Lexer, out *DSUser) { + 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 "Username": + out.Username = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks1(out *jwriter.Writer, in DSUser) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"Username\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Username)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v DSUser) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks1(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v DSUser) MarshalEasyJSON(w *jwriter.Writer) { + easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks1(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *DSUser) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks1(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *DSUser) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks1(l, v) +} +func easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks2(in *jlexer.Lexer, out *DSTopicsList) { + 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 "Topics": + if in.IsNull() { + in.Skip() + out.Topics = nil + } else { + in.Delim('[') + if out.Topics == nil { + if !in.IsDelim(']') { + out.Topics = make(DSTopics, 0, 8) + } else { + out.Topics = DSTopics{} + } + } else { + out.Topics = (out.Topics)[:0] + } + for !in.IsDelim(']') { + var v4 *DSTopic + if in.IsNull() { + in.Skip() + v4 = nil + } else { + if v4 == nil { + v4 = new(DSTopic) + } + (*v4).UnmarshalEasyJSON(in) + } + out.Topics = append(out.Topics, v4) + in.WantComma() + } + in.Delim(']') + } + case "MoreTopicsUrl": + out.MoreTopicsUrl = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks2(out *jwriter.Writer, in DSTopicsList) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"Topics\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + if in.Topics == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { + out.RawString("null") + } else { + out.RawByte('[') + for v5, v6 := range in.Topics { + if v5 > 0 { + out.RawByte(',') + } + if v6 == nil { + out.RawString("null") + } else { + (*v6).MarshalEasyJSON(out) + } + } + out.RawByte(']') + } + } + { + const prefix string = ",\"MoreTopicsUrl\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.MoreTopicsUrl)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v DSTopicsList) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks2(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v DSTopicsList) MarshalEasyJSON(w *jwriter.Writer) { + easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks2(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *DSTopicsList) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks2(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *DSTopicsList) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks2(l, v) +} +func easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks3(in *jlexer.Lexer, out *DSTopic) { + 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 "Slug": + out.Slug = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks3(out *jwriter.Writer, in DSTopic) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"Id\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Int(int(in.Id)) + } + { + const prefix string = ",\"Slug\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Slug)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v DSTopic) MarshalEasyJSON(w *jwriter.Writer) { + easyjsonCfe4e5f0EncodeGithubComFrancoispqtGojayBenchmarks3(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *DSTopic) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjsonCfe4e5f0DecodeGithubComFrancoispqtGojayBenchmarks3(l, v) +} diff --git a/benchmarks/medium_payload.go b/benchmarks/medium_payload.go new file mode 100644 index 0000000..93cc4df --- /dev/null +++ b/benchmarks/medium_payload.go @@ -0,0 +1,316 @@ +package benchmark + +import "github.com/francoispqt/gojay" + +// Response from Clearbit API. Size: 2.4kb +var MediumFixture = []byte(`{ + "person": { + "id": "d50887ca-a6ce-4e59-b89f-14f0b5d03b03", + "name": { + "fullName": "Leonid Bugaev", + "givenName": "Leonid", + "familyName": "Bugaev" + }, + "email": "leonsbox@gmail.com", + "gender": "male", + "location": "Saint Petersburg, Saint Petersburg, RU", + "geo": { + "city": "Saint Petersburg", + "state": "Saint Petersburg", + "country": "Russia", + "lat": 59.9342802, + "lng": 30.3350986 + }, + "bio": "Senior engineer at Granify.com", + "site": "http://flickfaver.com", + "avatar": "https://d1ts43dypk8bqh.cloudfront.net/v1/avatars/d50887ca-a6ce-4e59-b89f-14f0b5d03b03", + "employment": { + "name": "www.latera.ru", + "title": "Software Engineer", + "domain": "gmail.com" + }, + "facebook": { + "handle": "leonid.bugaev" + }, + "github": { + "handle": "buger", + "id": 14009, + "avatar": "https://avatars.githubusercontent.com/u/14009?v=3", + "company": "Granify", + "blog": "http://leonsbox.com", + "followers": 95, + "following": 10 + }, + "twitter": { + "handle": "flickfaver", + "id": 77004410, + "bio": null, + "followers": 2, + "following": 1, + "statuses": 5, + "favorites": 0, + "location": "", + "site": "http://flickfaver.com", + "avatar": null + }, + "linkedin": { + "handle": "in/leonidbugaev" + }, + "googleplus": { + "handle": null + }, + "angellist": { + "handle": "leonid-bugaev", + "id": 61541, + "bio": "Senior engineer at Granify.com", + "blog": "http://buger.github.com", + "site": "http://buger.github.com", + "followers": 41, + "avatar": "https://d1qb2nb5cznatu.cloudfront.net/users/61541-medium_jpg?1405474390" + }, + "klout": { + "handle": null, + "score": null + }, + "foursquare": { + "handle": null + }, + "aboutme": { + "handle": "leonid.bugaev", + "bio": null, + "avatar": null + }, + "gravatar": { + "handle": "buger", + "urls": [ + ], + "avatar": "http://1.gravatar.com/avatar/f7c8edd577d13b8930d5522f28123510", + "avatars": [ + { + "url": "http://1.gravatar.com/avatar/f7c8edd577d13b8930d5522f28123510", + "type": "thumbnail" + } + ] + }, + "fuzzy": false + }, + "company": null + }`) + +type CBAvatar struct { + Url string +} + +func (m *CBAvatar) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { + switch key { + case "avatars": + return dec.AddString(&m.Url) + } + return nil +} +func (m *CBAvatar) NKeys() int { + return 1 +} + +func (m *CBAvatar) MarshalJSONObject(enc *gojay.Encoder) { + enc.AddStringKey("url", m.Url) +} + +func (m *CBAvatar) IsNil() bool { + return m == nil +} + +type Avatars []*CBAvatar + +func (t *Avatars) UnmarshalJSONArray(dec *gojay.Decoder) error { + avatar := CBAvatar{} + *t = append(*t, &avatar) + return dec.AddObject(&avatar) +} + +func (m *Avatars) MarshalJSONArray(enc *gojay.Encoder) { + for _, e := range *m { + enc.AddObject(e) + } +} +func (m *Avatars) IsNil() bool { + return m == nil +} + +type CBGravatar struct { + Avatars Avatars +} + +func (m *CBGravatar) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { + switch key { + case "avatars": + return dec.AddArray(&m.Avatars) + } + return nil +} +func (m *CBGravatar) NKeys() int { + return 1 +} + +func (m *CBGravatar) MarshalJSONObject(enc *gojay.Encoder) { + enc.AddArrayKey("avatars", &m.Avatars) +} + +func (m *CBGravatar) IsNil() bool { + return m == nil +} + +type CBGithub struct { + Followers int +} + +func (m *CBGithub) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { + switch key { + case "followers": + return dec.AddInt(&m.Followers) + } + return nil +} + +func (m *CBGithub) NKeys() int { + return 1 +} + +func (m *CBGithub) MarshalJSONObject(enc *gojay.Encoder) { + enc.AddIntKey("followers", m.Followers) +} + +func (m *CBGithub) IsNil() bool { + return m == nil +} + +type CBName struct { + FullName string `json:"fullName"` +} + +func (m *CBName) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { + switch key { + case "fullName": + return dec.AddString(&m.FullName) + } + return nil +} + +func (m *CBName) NKeys() int { + return 1 +} + +func (m *CBName) MarshalJSONObject(enc *gojay.Encoder) { + enc.AddStringKey("fullName", m.FullName) +} + +func (m *CBName) IsNil() bool { + return m == nil +} + +type CBPerson struct { + Name *CBName `json:"name"` + Github *CBGithub `json:"github"` + Gravatar *CBGravatar +} + +func (m *CBPerson) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { + switch key { + case "name": + m.Name = &CBName{} + return dec.AddObject(m.Name) + case "github": + m.Github = &CBGithub{} + return dec.AddObject(m.Github) + case "gravatar": + m.Gravatar = &CBGravatar{} + return dec.AddObject(m.Gravatar) + } + return nil +} + +func (m *CBPerson) NKeys() int { + return 3 +} + +func (m *CBPerson) MarshalJSONObject(enc *gojay.Encoder) { + enc.AddObjectKey("name", m.Name) + enc.AddObjectKey("github", m.Github) + enc.AddObjectKey("gravatar", m.Gravatar) +} + +func (m *CBPerson) IsNil() bool { + return m == nil +} + +//easyjson:json +type MediumPayload struct { + Person *CBPerson `json:"person"` + Company string `json:"company"` +} + +func (m *MediumPayload) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { + switch key { + case "person": + m.Person = &CBPerson{} + return dec.AddObject(m.Person) + case "company": + dec.AddString(&m.Company) + } + return nil +} + +func (m *MediumPayload) NKeys() int { + return 2 +} + +func (m *MediumPayload) MarshalJSONObject(enc *gojay.Encoder) { + enc.AddObjectKey("person", m.Person) + // enc.AddStringKey("company", m.Company) +} + +func (m *MediumPayload) IsNil() bool { + return m == nil +} + +func NewMediumPayload() *MediumPayload { + return &MediumPayload{ + Company: "test", + Person: &CBPerson{ + Name: &CBName{ + FullName: "test", + }, + Github: &CBGithub{ + Followers: 100, + }, + Gravatar: &CBGravatar{ + Avatars: Avatars{ + &CBAvatar{ + Url: "http://test.com", + }, + &CBAvatar{ + Url: "http://test.com", + }, + &CBAvatar{ + Url: "http://test.com", + }, + &CBAvatar{ + Url: "http://test.com", + }, + &CBAvatar{ + Url: "http://test.com", + }, + &CBAvatar{ + Url: "http://test.com", + }, + &CBAvatar{ + Url: "http://test.com", + }, + &CBAvatar{ + Url: "http://test.com", + }, + }, + }, + }, + } +} diff --git a/benchmarks/medium_payload_easyjson.go b/benchmarks/medium_payload_easyjson.go new file mode 100644 index 0000000..b82191e --- /dev/null +++ b/benchmarks/medium_payload_easyjson.go @@ -0,0 +1,559 @@ +// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. +package benchmark + +import ( + json "encoding/json" + + easyjson "github.com/mailru/easyjson" + jlexer "github.com/mailru/easyjson/jlexer" + jwriter "github.com/mailru/easyjson/jwriter" +) + +// suppress unused package warning +var ( + _ *json.RawMessage + _ *jlexer.Lexer + _ *jwriter.Writer + _ easyjson.Marshaler +) + +func easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks(in *jlexer.Lexer, out *MediumPayload) { + 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 "person": + if in.IsNull() { + in.Skip() + out.Person = nil + } else { + if out.Person == nil { + out.Person = new(CBPerson) + } + (*out.Person).UnmarshalEasyJSON(in) + } + case "company": + out.Company = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks(out *jwriter.Writer, in MediumPayload) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"person\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + if in.Person == nil { + out.RawString("null") + } else { + (*in.Person).MarshalEasyJSON(out) + } + } + { + const prefix string = ",\"company\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Company)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v MediumPayload) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v MediumPayload) MarshalEasyJSON(w *jwriter.Writer) { + easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *MediumPayload) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *MediumPayload) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks(l, v) +} +func easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks1(in *jlexer.Lexer, out *CBPerson) { + 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": + if in.IsNull() { + in.Skip() + out.Name = nil + } else { + if out.Name == nil { + out.Name = new(CBName) + } + (*out.Name).UnmarshalEasyJSON(in) + } + case "github": + if in.IsNull() { + in.Skip() + out.Github = nil + } else { + if out.Github == nil { + out.Github = new(CBGithub) + } + (*out.Github).UnmarshalEasyJSON(in) + } + case "Gravatar": + if in.IsNull() { + in.Skip() + out.Gravatar = nil + } else { + if out.Gravatar == nil { + out.Gravatar = new(CBGravatar) + } + (*out.Gravatar).UnmarshalEasyJSON(in) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks1(out *jwriter.Writer, in CBPerson) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"name\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + if in.Name == nil { + out.RawString("null") + } else { + (*in.Name).MarshalEasyJSON(out) + } + } + { + const prefix string = ",\"github\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + if in.Github == nil { + out.RawString("null") + } else { + (*in.Github).MarshalEasyJSON(out) + } + } + { + const prefix string = ",\"Gravatar\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + if in.Gravatar == nil { + out.RawString("null") + } else { + (*in.Gravatar).MarshalEasyJSON(out) + } + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v CBPerson) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks1(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v CBPerson) MarshalEasyJSON(w *jwriter.Writer) { + easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks1(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *CBPerson) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks1(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *CBPerson) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks1(l, v) +} +func easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks2(in *jlexer.Lexer, out *CBName) { + 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 "fullName": + out.FullName = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks2(out *jwriter.Writer, in CBName) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"fullName\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.FullName)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v CBName) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks2(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v CBName) MarshalEasyJSON(w *jwriter.Writer) { + easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks2(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *CBName) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks2(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *CBName) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks2(l, v) +} +func easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks3(in *jlexer.Lexer, out *CBGravatar) { + 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 "Avatars": + if in.IsNull() { + in.Skip() + out.Avatars = nil + } else { + in.Delim('[') + if out.Avatars == nil { + if !in.IsDelim(']') { + out.Avatars = make(Avatars, 0, 8) + } else { + out.Avatars = Avatars{} + } + } else { + out.Avatars = (out.Avatars)[:0] + } + for !in.IsDelim(']') { + var v1 *CBAvatar + if in.IsNull() { + in.Skip() + v1 = nil + } else { + if v1 == nil { + v1 = new(CBAvatar) + } + (*v1).UnmarshalEasyJSON(in) + } + out.Avatars = append(out.Avatars, v1) + in.WantComma() + } + in.Delim(']') + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks3(out *jwriter.Writer, in CBGravatar) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"Avatars\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + if in.Avatars == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { + out.RawString("null") + } else { + out.RawByte('[') + for v2, v3 := range in.Avatars { + if v2 > 0 { + out.RawByte(',') + } + if v3 == nil { + out.RawString("null") + } else { + (*v3).MarshalEasyJSON(out) + } + } + out.RawByte(']') + } + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v CBGravatar) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks3(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v CBGravatar) MarshalEasyJSON(w *jwriter.Writer) { + easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks3(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *CBGravatar) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks3(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *CBGravatar) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks3(l, v) +} +func easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks4(in *jlexer.Lexer, out *CBGithub) { + 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 "Followers": + out.Followers = int(in.Int()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks4(out *jwriter.Writer, in CBGithub) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"Followers\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Int(int(in.Followers)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v CBGithub) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks4(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v CBGithub) MarshalEasyJSON(w *jwriter.Writer) { + easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks4(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *CBGithub) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks4(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *CBGithub) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks4(l, v) +} +func easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks5(in *jlexer.Lexer, out *CBAvatar) { + 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 "Url": + out.Url = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks5(out *jwriter.Writer, in CBAvatar) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"Url\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Url)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v CBAvatar) MarshalEasyJSON(w *jwriter.Writer) { + easyjsonB0500db0EncodeGithubComFrancoispqtGojayBenchmarks5(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *CBAvatar) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjsonB0500db0DecodeGithubComFrancoispqtGojayBenchmarks5(l, v) +} diff --git a/benchmarks/small_payload.go b/benchmarks/small_payload.go new file mode 100644 index 0000000..d1ec087 --- /dev/null +++ b/benchmarks/small_payload.go @@ -0,0 +1,76 @@ +package benchmark + +import "github.com/francoispqt/gojay" + +var SmallFixture = []byte(`{"st": 1,"sid": 486,"tt": "active","gr": 0,"uuid": "de305d54-75b4-431b-adb2-eb6b9e546014","ip": "127.0.0.1","ua": "user_agent","tz": -6,"v": 1}`) + +//easyjson:json +type SmallPayload struct { + St int + Sid int + Tt string + Gr int + Uuid string + Ip string + Ua string + Tz int + V int +} + +func (t *SmallPayload) MarshalJSONObject(enc *gojay.Encoder) { + enc.AddIntKey("st", t.St) + enc.AddIntKey("sid", t.Sid) + enc.AddStringKey("tt", t.Tt) + enc.AddIntKey("gr", t.Gr) + enc.AddStringKey("uuid", t.Uuid) + enc.AddStringKey("ip", t.Ip) + enc.AddStringKey("ua", t.Ua) + enc.AddIntKey("tz", t.Tz) + enc.AddIntKey("v", t.V) +} + +func (t *SmallPayload) IsNil() bool { + return t == nil +} + +func (t *SmallPayload) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { + switch key { + case "st": + return dec.AddInt(&t.St) + case "sid": + return dec.AddInt(&t.Sid) + case "gr": + return dec.AddInt(&t.Gr) + case "tz": + return dec.AddInt(&t.Tz) + case "v": + return dec.AddInt(&t.V) + case "tt": + return dec.AddString(&t.Tt) + case "uuid": + return dec.AddString(&t.Uuid) + case "ip": + return dec.AddString(&t.Ip) + case "ua": + return dec.AddString(&t.Ua) + } + return nil +} + +func (t *SmallPayload) NKeys() int { + return 9 +} + +func NewSmallPayload() *SmallPayload { + return &SmallPayload{ + St: 1, + Sid: 2, + Tt: "TestString", + Gr: 4, + Uuid: "8f9a65eb-4807-4d57-b6e0-bda5d62f1429", + Ip: "127.0.0.1", + Ua: "Mozilla", + Tz: 8, + V: 6, + } +} diff --git a/benchmarks/small_payload_easyjson.go b/benchmarks/small_payload_easyjson.go new file mode 100644 index 0000000..6b20c37 --- /dev/null +++ b/benchmarks/small_payload_easyjson.go @@ -0,0 +1,186 @@ +// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. +package benchmark + +import ( + json "encoding/json" + + easyjson "github.com/mailru/easyjson" + jlexer "github.com/mailru/easyjson/jlexer" + jwriter "github.com/mailru/easyjson/jwriter" +) + +// suppress unused package warning +var ( + _ *json.RawMessage + _ *jlexer.Lexer + _ *jwriter.Writer + _ easyjson.Marshaler +) + +func easyjson890029d8DecodeGithubComFrancoispqtGojayBenchmarks(in *jlexer.Lexer, out *SmallPayload) { + 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 "St": + out.St = int(in.Int()) + case "Sid": + out.Sid = int(in.Int()) + case "Tt": + out.Tt = string(in.String()) + case "Gr": + out.Gr = int(in.Int()) + case "Uuid": + out.Uuid = string(in.String()) + case "Ip": + out.Ip = string(in.String()) + case "Ua": + out.Ua = string(in.String()) + case "Tz": + out.Tz = int(in.Int()) + case "V": + out.V = int(in.Int()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson890029d8EncodeGithubComFrancoispqtGojayBenchmarks(out *jwriter.Writer, in SmallPayload) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"St\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Int(int(in.St)) + } + { + const prefix string = ",\"Sid\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Int(int(in.Sid)) + } + { + const prefix string = ",\"Tt\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Tt)) + } + { + const prefix string = ",\"Gr\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Int(int(in.Gr)) + } + { + const prefix string = ",\"Uuid\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Uuid)) + } + { + const prefix string = ",\"Ip\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Ip)) + } + { + const prefix string = ",\"Ua\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Ua)) + } + { + const prefix string = ",\"Tz\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Int(int(in.Tz)) + } + { + const prefix string = ",\"V\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Int(int(in.V)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v SmallPayload) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson890029d8EncodeGithubComFrancoispqtGojayBenchmarks(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v SmallPayload) MarshalEasyJSON(w *jwriter.Writer) { + easyjson890029d8EncodeGithubComFrancoispqtGojayBenchmarks(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *SmallPayload) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson890029d8DecodeGithubComFrancoispqtGojayBenchmarks(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *SmallPayload) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson890029d8DecodeGithubComFrancoispqtGojayBenchmarks(l, v) +} diff --git a/go.mod b/go.mod index 48a534c..0a800ea 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,4 @@ module github.com/goccy/go-json go 1.12 -require ( - github.com/francoispqt/gojay v1.2.13 - github.com/json-iterator/go v1.1.9 - golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 -) +require golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 diff --git a/go.sum b/go.sum index 4ec2a93..3ab73ea 100644 --- a/go.sum +++ b/go.sum @@ -1,179 +1,2 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= -dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= -dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= -dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= -dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= -git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= -github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= -github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= -github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= -github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= -github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= -github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= -github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= -github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= -github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= -github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= -github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= -github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= -github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= -github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= -github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= -github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= -github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= -github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= -github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= -github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= -github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= -github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= -github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= -go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= -golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= -golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= -google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=