mirror of
https://github.com/json-iterator/go.git
synced 2025-04-20 11:28:49 +02:00
consolidate struct tags tests
This commit is contained in:
parent
dc3395f770
commit
6fded6eb5f
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// S1 TEST ONLY
|
|
||||||
type S1 struct {
|
|
||||||
S1F string
|
|
||||||
}
|
|
||||||
|
|
||||||
// S2 TEST ONLY
|
|
||||||
type S2 struct {
|
|
||||||
S2F string
|
|
||||||
}
|
|
||||||
|
|
||||||
// S3 TEST ONLY
|
|
||||||
type S3 struct {
|
|
||||||
S3F string
|
|
||||||
}
|
|
||||||
|
|
||||||
// S4 TEST ONLY
|
|
||||||
type S4 struct {
|
|
||||||
S4F string
|
|
||||||
}
|
|
||||||
|
|
||||||
// S5 TEST ONLY
|
|
||||||
type S5 struct {
|
|
||||||
S5F string
|
|
||||||
}
|
|
||||||
|
|
||||||
// S6 TEST ONLY
|
|
||||||
type S6 struct {
|
|
||||||
S6F string
|
|
||||||
}
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
S1 `json:"F1"`
|
|
||||||
S2 `json:"f2"`
|
|
||||||
S3 `json:"-"`
|
|
||||||
S4 `json:"-,"`
|
|
||||||
S5 `json:","`
|
|
||||||
S6 `json:""`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// E TEST ONLY
|
|
||||||
type E struct {
|
|
||||||
E1 string
|
|
||||||
}
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 string `json:"F1"`
|
|
||||||
F2 string `json:"f2"`
|
|
||||||
F3 string `json:"-"`
|
|
||||||
F4 string `json:"-,"`
|
|
||||||
F5 string `json:","`
|
|
||||||
F6 string `json:""`
|
|
||||||
E `json:"e"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// S1 TEST ONLY
|
|
||||||
type S1 struct {
|
|
||||||
S1F string
|
|
||||||
}
|
|
||||||
|
|
||||||
// S2 TEST ONLY
|
|
||||||
type S2 struct {
|
|
||||||
S2F string
|
|
||||||
}
|
|
||||||
|
|
||||||
// S3 TEST ONLY
|
|
||||||
type S3 struct {
|
|
||||||
S3F string
|
|
||||||
}
|
|
||||||
|
|
||||||
// S4 TEST ONLY
|
|
||||||
type S4 struct {
|
|
||||||
S4F string
|
|
||||||
}
|
|
||||||
|
|
||||||
// S5 TEST ONLY
|
|
||||||
type S5 struct {
|
|
||||||
S5F string
|
|
||||||
}
|
|
||||||
|
|
||||||
// S6 TEST ONLY
|
|
||||||
type S6 struct {
|
|
||||||
S6F string
|
|
||||||
}
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 S1 `json:"F1"`
|
|
||||||
F2 S2 `json:"f2"`
|
|
||||||
F3 S3 `json:"-"`
|
|
||||||
F4 S4 `json:"-,"`
|
|
||||||
F5 S5 `json:","`
|
|
||||||
F6 S6 `json:""`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 bool `json:"F1"`
|
|
||||||
F2 bool `json:"F2,omitempty"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// E TEST ONLY
|
|
||||||
type E struct {
|
|
||||||
F string `json:"F,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
E
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 float32 `json:"F1"`
|
|
||||||
F2 float32 `json:"F2,omitempty"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 int32 `json:"F1"`
|
|
||||||
F2 int32 `json:"F2,omitempty"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 map[string]string `json:"F1"`
|
|
||||||
F2 map[string]string `json:"F2,omitempty"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 *bool `json:"F1"`
|
|
||||||
F2 *bool `json:"F2,omitempty"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 *float32 `json:"F1"`
|
|
||||||
F2 *float32 `json:"F2,omitempty"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 *int32 `json:"F1"`
|
|
||||||
F2 *int32 `json:"F2,omitempty"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 *map[string]string `json:"F1"`
|
|
||||||
F2 *map[string]string `json:"F2,omitempty"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 *[]string `json:"F1"`
|
|
||||||
F2 *[]string `json:"F2,omitempty"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 string `json:"F1"`
|
|
||||||
F2 string `json:"F2,omitempty"`
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 *string `json:"F1"`
|
|
||||||
F2 *string `json:"F2,omitempty"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F *jm `json:"f,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type jm string
|
|
||||||
|
|
||||||
func (t *jm) UnmarshalJSON(b []byte) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t jm) MarshalJSON() ([]byte, error) {
|
|
||||||
return []byte(`""`), nil
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F *tm `json:"f,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type tm string
|
|
||||||
|
|
||||||
func (t *tm) UnmarshalText(b []byte) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t tm) MarshalText() ([]byte, error) {
|
|
||||||
return []byte(`""`), nil
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F *jm `json:"f,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type jm struct{}
|
|
||||||
|
|
||||||
func (t *jm) UnmarshalJSON(b []byte) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t jm) MarshalJSON() ([]byte, error) {
|
|
||||||
return []byte(`""`), nil
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F *tm `json:"f,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type tm struct{}
|
|
||||||
|
|
||||||
func (t *tm) UnmarshalText(b []byte) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t tm) MarshalText() ([]byte, error) {
|
|
||||||
return []byte(`""`), nil
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 *uint32 `json:"F1"`
|
|
||||||
F2 *uint32 `json:"F2,omitempty"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 []string `json:"F1"`
|
|
||||||
F2 []string `json:"F2,omitempty"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 string `json:"F1"`
|
|
||||||
F2 string `json:"F2,omitempty"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F jm `json:"f,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type jm string
|
|
||||||
|
|
||||||
func (t *jm) UnmarshalJSON(b []byte) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t jm) MarshalJSON() ([]byte, error) {
|
|
||||||
return []byte(`""`), nil
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F tm `json:"f,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type tm string
|
|
||||||
|
|
||||||
func (t *tm) UnmarshalText(b []byte) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t tm) MarshalText() ([]byte, error) {
|
|
||||||
return []byte(`""`), nil
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F struct{} `json:"f,omitempty"` // omitempty is meaningless here
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F jm `json:"f,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type jm struct{}
|
|
||||||
|
|
||||||
func (t *jm) UnmarshalJSON(b []byte) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t jm) MarshalJSON() ([]byte, error) {
|
|
||||||
return []byte(`""`), nil
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F tm `json:"f,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type tm struct{}
|
|
||||||
|
|
||||||
func (t *tm) UnmarshalText(b []byte) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t tm) MarshalText() ([]byte, error) {
|
|
||||||
return []byte(`""`), nil
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 uint32 `json:"F1"`
|
|
||||||
F2 uint32 `json:"F2,omitempty"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 bool `json:"F1"`
|
|
||||||
F2 bool `json:"F2,string"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 byte `json:"F1"`
|
|
||||||
F2 byte `json:"F2,string"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 float32 `json:"F1"`
|
|
||||||
F2 float32 `json:"F2,string"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 float64 `json:"F1"`
|
|
||||||
F2 float64 `json:"F2,string"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 int16 `json:"F1"`
|
|
||||||
F2 int16 `json:"F2,string"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 int32 `json:"F1"`
|
|
||||||
F2 int32 `json:"F2,string"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 int8 `json:"F1"`
|
|
||||||
F2 int8 `json:"F2,string"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 string `json:"F1"`
|
|
||||||
F2 string `json:"F2,string"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 uint16 `json:"F1"`
|
|
||||||
F2 uint16 `json:"F2,string"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 uint32 `json:"F1"`
|
|
||||||
F2 uint32 `json:"F2,string"`
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
fuzz "github.com/google/gofuzz"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Roundtrip(t *testing.T) {
|
|
||||||
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
var before typeForTest
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
|
|
||||||
jbStd, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
||||||
t.Fatal("stdlib marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
||||||
}
|
|
||||||
if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
||||||
t.Fatal("jsoniter marshal produced empty result and no error")
|
|
||||||
}
|
|
||||||
if string(jbStd) != string(jbIter) {
|
|
||||||
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
||||||
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterStd typeForTest
|
|
||||||
err = json.Unmarshal(jbIter, &afterStd)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
var afterIter typeForTest
|
|
||||||
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
||||||
err, indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
||||||
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
||||||
dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indentStr = "> "
|
|
||||||
|
|
||||||
func fingerprint(obj interface{}) string {
|
|
||||||
c := spew.ConfigState{
|
|
||||||
SortKeys: true,
|
|
||||||
SpewKeys: true,
|
|
||||||
}
|
|
||||||
return c.Sprintf("%v", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(obj interface{}) string {
|
|
||||||
cfg := spew.ConfigState{
|
|
||||||
Indent: indentStr,
|
|
||||||
}
|
|
||||||
return cfg.Sdump(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indent(src []byte, prefix string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := json.Indent(&buf, src, prefix, indentStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("!!! %v", err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var obj typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&obj)
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
jb, err := fn(obj)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
|
|
||||||
}
|
|
||||||
_ = jb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
|
|
||||||
t.ReportAllocs()
|
|
||||||
t.ResetTimer()
|
|
||||||
|
|
||||||
var before typeForTest
|
|
||||||
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
|
|
||||||
fz.Fuzz(&before)
|
|
||||||
jb, err := json.Marshal(before)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
|
||||||
var after typeForTest
|
|
||||||
err = fn(jb, &after)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardMarshal(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "stdlib", json.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkStandardUnmarshal(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
|
|
||||||
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 uint8 `json:"F1"`
|
|
||||||
F2 uint8 `json:"F2,string"`
|
|
||||||
}
|
|
275
type_tests/struct_tags_test.go
Normal file
275
type_tests/struct_tags_test.go
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
testCases = append(testCases,
|
||||||
|
(*EmbeddedFieldName)(nil),
|
||||||
|
(*StringFieldName)(nil),
|
||||||
|
(*StructFieldName)(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 bool `json:"F1"`
|
||||||
|
F2 bool `json:"F2,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*EmbeddedOmitEmpty)(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 float32 `json:"F1"`
|
||||||
|
F2 float32 `json:"F2,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 int32 `json:"F1"`
|
||||||
|
F2 int32 `json:"F2,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 map[string]string `json:"F1"`
|
||||||
|
F2 map[string]string `json:"F2,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 *bool `json:"F1"`
|
||||||
|
F2 *bool `json:"F2,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 *float32 `json:"F1"`
|
||||||
|
F2 *float32 `json:"F2,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 *int32 `json:"F1"`
|
||||||
|
F2 *int32 `json:"F2,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 *map[string]string `json:"F1"`
|
||||||
|
F2 *map[string]string `json:"F2,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 *[]string `json:"F1"`
|
||||||
|
F2 *[]string `json:"F2,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 string `json:"F1"`
|
||||||
|
F2 string `json:"F2,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 *string `json:"F1"`
|
||||||
|
F2 *string `json:"F2,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F *jm `json:"f,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F *tm `json:"f,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F *sjm `json:"f,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F *tm `json:"f,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 *uint32 `json:"F1"`
|
||||||
|
F2 *uint32 `json:"F2,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 []string `json:"F1"`
|
||||||
|
F2 []string `json:"F2,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 string `json:"F1"`
|
||||||
|
F2 string `json:"F2,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F jm `json:"f,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F tm `json:"f,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F struct{} `json:"f,omitempty"` // omitempty is meaningless here
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F sjm `json:"f,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F stm `json:"f,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 uint32 `json:"F1"`
|
||||||
|
F2 uint32 `json:"F2,omitempty"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 bool `json:"F1"`
|
||||||
|
F2 bool `json:"F2,string"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 byte `json:"F1"`
|
||||||
|
F2 byte `json:"F2,string"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 float32 `json:"F1"`
|
||||||
|
F2 float32 `json:"F2,string"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 float64 `json:"F1"`
|
||||||
|
F2 float64 `json:"F2,string"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 int8 `json:"F1"`
|
||||||
|
F2 int8 `json:"F2,string"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 int16 `json:"F1"`
|
||||||
|
F2 int16 `json:"F2,string"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 int32 `json:"F1"`
|
||||||
|
F2 int32 `json:"F2,string"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 string `json:"F1"`
|
||||||
|
F2 string `json:"F2,string"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 uint8 `json:"F1"`
|
||||||
|
F2 uint8 `json:"F2,string"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 uint16 `json:"F1"`
|
||||||
|
F2 uint16 `json:"F2,string"`
|
||||||
|
})(nil),
|
||||||
|
(*struct {
|
||||||
|
F1 uint32 `json:"F1"`
|
||||||
|
F2 uint32 `json:"F2,string"`
|
||||||
|
})(nil),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// S1 TEST ONLY
|
||||||
|
type EmbeddedFieldNameS1 struct {
|
||||||
|
S1F string
|
||||||
|
}
|
||||||
|
|
||||||
|
// S2 TEST ONLY
|
||||||
|
type EmbeddedFieldNameS2 struct {
|
||||||
|
S2F string
|
||||||
|
}
|
||||||
|
|
||||||
|
// S3 TEST ONLY
|
||||||
|
type EmbeddedFieldNameS3 struct {
|
||||||
|
S3F string
|
||||||
|
}
|
||||||
|
|
||||||
|
// S4 TEST ONLY
|
||||||
|
type EmbeddedFieldNameS4 struct {
|
||||||
|
S4F string
|
||||||
|
}
|
||||||
|
|
||||||
|
// S5 TEST ONLY
|
||||||
|
type EmbeddedFieldNameS5 struct {
|
||||||
|
S5F string
|
||||||
|
}
|
||||||
|
|
||||||
|
// S6 TEST ONLY
|
||||||
|
type EmbeddedFieldNameS6 struct {
|
||||||
|
S6F string
|
||||||
|
}
|
||||||
|
|
||||||
|
type EmbeddedFieldName struct {
|
||||||
|
EmbeddedFieldNameS1 `json:"F1"`
|
||||||
|
EmbeddedFieldNameS2 `json:"f2"`
|
||||||
|
EmbeddedFieldNameS3 `json:"-"`
|
||||||
|
EmbeddedFieldNameS4 `json:"-,"`
|
||||||
|
EmbeddedFieldNameS5 `json:","`
|
||||||
|
EmbeddedFieldNameS6 `json:""`
|
||||||
|
}
|
||||||
|
|
||||||
|
type StringFieldNameE struct {
|
||||||
|
E1 string
|
||||||
|
}
|
||||||
|
|
||||||
|
type StringFieldName struct {
|
||||||
|
F1 string `json:"F1"`
|
||||||
|
F2 string `json:"f2"`
|
||||||
|
F3 string `json:"-"`
|
||||||
|
F4 string `json:"-,"`
|
||||||
|
F5 string `json:","`
|
||||||
|
F6 string `json:""`
|
||||||
|
StringFieldNameE `json:"e"`
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type StructFieldNameS1 struct {
|
||||||
|
S1F string
|
||||||
|
}
|
||||||
|
|
||||||
|
type StructFieldNameS2 struct {
|
||||||
|
S2F string
|
||||||
|
}
|
||||||
|
|
||||||
|
type StructFieldNameS3 struct {
|
||||||
|
S3F string
|
||||||
|
}
|
||||||
|
|
||||||
|
type StructFieldNameS4 struct {
|
||||||
|
S4F string
|
||||||
|
}
|
||||||
|
|
||||||
|
type StructFieldNameS5 struct {
|
||||||
|
S5F string
|
||||||
|
}
|
||||||
|
|
||||||
|
type StructFieldNameS6 struct {
|
||||||
|
S6F string
|
||||||
|
}
|
||||||
|
|
||||||
|
type StructFieldName struct {
|
||||||
|
F1 StructFieldNameS1 `json:"F1"`
|
||||||
|
F2 StructFieldNameS2 `json:"f2"`
|
||||||
|
F3 StructFieldNameS3 `json:"-"`
|
||||||
|
F4 StructFieldNameS4 `json:"-,"`
|
||||||
|
F5 StructFieldNameS5 `json:","`
|
||||||
|
F6 StructFieldNameS6 `json:""`
|
||||||
|
}
|
||||||
|
type EmbeddedOmitEmptyE struct {
|
||||||
|
F string `json:"F,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EmbeddedOmitEmpty struct {
|
||||||
|
EmbeddedOmitEmptyE
|
||||||
|
}
|
||||||
|
|
||||||
|
type jm string
|
||||||
|
|
||||||
|
func (t *jm) UnmarshalJSON(b []byte) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t jm) MarshalJSON() ([]byte, error) {
|
||||||
|
return []byte(`""`), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type tm string
|
||||||
|
|
||||||
|
func (t *tm) UnmarshalText(b []byte) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t tm) MarshalText() ([]byte, error) {
|
||||||
|
return []byte(`""`), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type sjm struct{}
|
||||||
|
|
||||||
|
func (t *sjm) UnmarshalJSON(b []byte) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t sjm) MarshalJSON() ([]byte, error) {
|
||||||
|
return []byte(`""`), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type stm struct{}
|
||||||
|
|
||||||
|
func (t *stm) UnmarshalText(b []byte) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t stm) MarshalText() ([]byte, error) {
|
||||||
|
return []byte(`""`), nil
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user