mirror of
https://github.com/json-iterator/go.git
synced 2025-04-20 11:28:49 +02:00
consolidate struct tests
This commit is contained in:
parent
bd4e013f98
commit
dc3395f770
@ -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,20 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeA struct {
|
|
||||||
Byte1 byte
|
|
||||||
Byte2 byte
|
|
||||||
Bool1 bool
|
|
||||||
Bool2 bool
|
|
||||||
Int8 int8
|
|
||||||
Int16 int16
|
|
||||||
Int32 int32
|
|
||||||
Uint8 uint8
|
|
||||||
Uint16 uint16
|
|
||||||
Uint32 uint32
|
|
||||||
Float32 float32
|
|
||||||
Float64 float64
|
|
||||||
String1 string
|
|
||||||
String2 string
|
|
||||||
}
|
|
||||||
|
|
||||||
type typeForTest typeA
|
|
@ -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,8 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// Embedded TEST ONLY
|
|
||||||
type Embedded float64
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
Embedded
|
|
||||||
}
|
|
@ -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,8 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// Embedded TEST ONLY
|
|
||||||
type Embedded int32
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
Embedded
|
|
||||||
}
|
|
@ -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,57 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MarshalerForTest TEST ONLY
|
|
||||||
type MarshalerForTest string
|
|
||||||
|
|
||||||
func encode(str string) string {
|
|
||||||
buf := bytes.Buffer{}
|
|
||||||
b64 := base64.NewEncoder(base64.StdEncoding, &buf)
|
|
||||||
if _, err := b64.Write([]byte(str)); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if err := b64.Close(); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func decode(str string) string {
|
|
||||||
if len(str) == 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
b64 := base64.NewDecoder(base64.StdEncoding, strings.NewReader(str))
|
|
||||||
bs := make([]byte, len(str))
|
|
||||||
if n, err := b64.Read(bs); err != nil {
|
|
||||||
panic(err)
|
|
||||||
} else {
|
|
||||||
bs = bs[:n]
|
|
||||||
}
|
|
||||||
return string(bs)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON TEST ONLY
|
|
||||||
func (m MarshalerForTest) MarshalJSON() ([]byte, error) {
|
|
||||||
return []byte(`"MANUAL__` + encode(string(m)) + `"`), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON TEST ONLY
|
|
||||||
func (m *MarshalerForTest) UnmarshalJSON(text []byte) error {
|
|
||||||
*m = MarshalerForTest(decode(strings.TrimPrefix(strings.Trim(string(text), `"`), "MANUAL__")))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ json.Marshaler = *new(MarshalerForTest)
|
|
||||||
var _ json.Unmarshaler = new(MarshalerForTest)
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 float64
|
|
||||||
MarshalerForTest
|
|
||||||
F2 int32
|
|
||||||
}
|
|
@ -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,8 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// Embedded TEST ONLY
|
|
||||||
type Embedded map[string]string
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
Embedded
|
|
||||||
}
|
|
@ -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,8 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// Embedded TEST ONLY
|
|
||||||
type Embedded float64
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
*Embedded
|
|
||||||
}
|
|
@ -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,8 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// Embedded TEST ONLY
|
|
||||||
type Embedded int32
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
*Embedded
|
|
||||||
}
|
|
@ -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,8 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// Embedded TEST ONLY
|
|
||||||
type Embedded map[string]string
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
*Embedded
|
|
||||||
}
|
|
@ -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,8 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// Embedded TEST ONLY
|
|
||||||
type Embedded []string
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
*Embedded
|
|
||||||
}
|
|
@ -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,8 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// Embedded TEST ONLY
|
|
||||||
type Embedded string
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
*Embedded
|
|
||||||
}
|
|
@ -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,17 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// Embedded TEST ONLY
|
|
||||||
type Embedded struct {
|
|
||||||
String string
|
|
||||||
Int int32
|
|
||||||
Float float64
|
|
||||||
Struct struct {
|
|
||||||
X string
|
|
||||||
}
|
|
||||||
Slice []string
|
|
||||||
Map map[string]string
|
|
||||||
}
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
*Embedded
|
|
||||||
}
|
|
@ -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,8 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// Embedded TEST ONLY
|
|
||||||
type Embedded []string
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
Embedded
|
|
||||||
}
|
|
@ -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,8 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// Embedded TEST ONLY
|
|
||||||
type Embedded string
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
Embedded
|
|
||||||
}
|
|
@ -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,8 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// Embedded TEST ONLY
|
|
||||||
type Embedded string
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
Embedded `json:"othername"`
|
|
||||||
}
|
|
@ -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,17 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// Embedded TEST ONLY
|
|
||||||
type Embedded struct {
|
|
||||||
String string
|
|
||||||
Int int32
|
|
||||||
Float float64
|
|
||||||
Struct struct {
|
|
||||||
X string
|
|
||||||
}
|
|
||||||
Slice []string
|
|
||||||
Map map[string]string
|
|
||||||
}
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
Embedded
|
|
||||||
}
|
|
@ -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,17 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// E1 TEST ONLY
|
|
||||||
type E1 struct {
|
|
||||||
F1 int32
|
|
||||||
}
|
|
||||||
|
|
||||||
// E2 TEST ONLY
|
|
||||||
type E2 struct {
|
|
||||||
F2 string
|
|
||||||
}
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
E1
|
|
||||||
E2
|
|
||||||
F1 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,23 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// DoubleEmbedded TEST ONLY
|
|
||||||
type DoubleEmbedded struct {
|
|
||||||
F1 int32 `json:"F1"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Embedded1 TEST ONLY
|
|
||||||
type Embedded1 struct {
|
|
||||||
DoubleEmbedded
|
|
||||||
F1 int32
|
|
||||||
}
|
|
||||||
|
|
||||||
// Embedded2 TEST ONLY
|
|
||||||
type Embedded2 struct {
|
|
||||||
F1 int32 `json:"F1"`
|
|
||||||
DoubleEmbedded
|
|
||||||
}
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
Embedded1
|
|
||||||
Embedded2
|
|
||||||
}
|
|
@ -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
|
|
||||||
|
|
||||||
// Embedded1 TEST ONLY
|
|
||||||
type Embedded1 struct {
|
|
||||||
F1 int32 `json:"F1"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Embedded2 TEST ONLY
|
|
||||||
type Embedded2 struct {
|
|
||||||
F1 int32 `json:"F1"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
Embedded1
|
|
||||||
Embedded2
|
|
||||||
}
|
|
@ -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
|
|
||||||
|
|
||||||
// Embedded1 TEST ONLY
|
|
||||||
type Embedded1 struct {
|
|
||||||
F1 int32
|
|
||||||
}
|
|
||||||
|
|
||||||
// Embedded2 TEST ONLY
|
|
||||||
type Embedded2 struct {
|
|
||||||
F1 int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
Embedded1
|
|
||||||
Embedded2
|
|
||||||
}
|
|
@ -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
|
|
||||||
|
|
||||||
// Embedded1 TEST ONLY
|
|
||||||
type Embedded1 struct {
|
|
||||||
F1 int32
|
|
||||||
}
|
|
||||||
|
|
||||||
// Embedded2 TEST ONLY
|
|
||||||
type Embedded2 struct {
|
|
||||||
F1 int32 `json:"F1"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
Embedded1
|
|
||||||
Embedded2
|
|
||||||
}
|
|
@ -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,26 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// DoubleEmbedded1 TEST ONLY
|
|
||||||
type DoubleEmbedded1 struct {
|
|
||||||
F1 int32 `json:"F1"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Embedded1 TEST ONLY
|
|
||||||
type Embedded1 struct {
|
|
||||||
DoubleEmbedded1
|
|
||||||
}
|
|
||||||
|
|
||||||
// DoubleEmbedded2 TEST ONLY
|
|
||||||
type DoubleEmbedded2 struct {
|
|
||||||
F1 int32 `json:"F1"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Embedded2 TEST ONLY
|
|
||||||
type Embedded2 struct {
|
|
||||||
DoubleEmbedded2
|
|
||||||
}
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
Embedded1
|
|
||||||
Embedded2
|
|
||||||
}
|
|
@ -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,26 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// DoubleEmbedded1 TEST ONLY
|
|
||||||
type DoubleEmbedded1 struct {
|
|
||||||
F1 int32
|
|
||||||
}
|
|
||||||
|
|
||||||
// Embedded1 TEST ONLY
|
|
||||||
type Embedded1 struct {
|
|
||||||
DoubleEmbedded1
|
|
||||||
}
|
|
||||||
|
|
||||||
// DoubleEmbedded2 TEST ONLY
|
|
||||||
type DoubleEmbedded2 struct {
|
|
||||||
F1 int32
|
|
||||||
}
|
|
||||||
|
|
||||||
// Embedded2 TEST ONLY
|
|
||||||
type Embedded2 struct {
|
|
||||||
DoubleEmbedded2
|
|
||||||
}
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
Embedded1
|
|
||||||
Embedded2
|
|
||||||
}
|
|
@ -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,26 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
// DoubleEmbedded1 TEST ONLY
|
|
||||||
type DoubleEmbedded1 struct {
|
|
||||||
F1 int32
|
|
||||||
}
|
|
||||||
|
|
||||||
// Embedded1 TEST ONLY
|
|
||||||
type Embedded1 struct {
|
|
||||||
DoubleEmbedded1
|
|
||||||
}
|
|
||||||
|
|
||||||
// DoubleEmbedded2 TEST ONLY
|
|
||||||
type DoubleEmbedded2 struct {
|
|
||||||
F1 int32 `json:"F1"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Embedded2 TEST ONLY
|
|
||||||
type Embedded2 struct {
|
|
||||||
DoubleEmbedded2
|
|
||||||
}
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
Embedded1
|
|
||||||
Embedded2
|
|
||||||
}
|
|
@ -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 [4]*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,5 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F [4]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,9 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeA1 string
|
|
||||||
type typeA2 [4]typeA1
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 [4]typeA1
|
|
||||||
F2 typeA2
|
|
||||||
}
|
|
@ -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,7 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 [4]string
|
|
||||||
F2 [4]string
|
|
||||||
F3 [4]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,9 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F [4]struct {
|
|
||||||
F1 string
|
|
||||||
F2 string
|
|
||||||
F3 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,3 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct{}
|
|
@ -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 typeA struct{}
|
|
||||||
|
|
||||||
type typeForTest typeA
|
|
@ -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,20 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
Byte1 byte
|
|
||||||
Byte2 byte
|
|
||||||
Bool1 bool
|
|
||||||
Bool2 bool
|
|
||||||
Int8 int8
|
|
||||||
Int16 int16
|
|
||||||
Int32 int32
|
|
||||||
Int64 int64
|
|
||||||
Uint8 uint8
|
|
||||||
Uint16 uint16
|
|
||||||
Uint32 uint32
|
|
||||||
Uint64 uint64
|
|
||||||
Float32 float32
|
|
||||||
Float64 float64
|
|
||||||
String1 string
|
|
||||||
String2 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,5 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F float64
|
|
||||||
}
|
|
@ -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,7 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeA float64
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F typeA
|
|
||||||
}
|
|
@ -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,7 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 float64
|
|
||||||
F2 float64
|
|
||||||
F3 float64
|
|
||||||
}
|
|
@ -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,9 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeA float64
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 typeA
|
|
||||||
F2 typeA
|
|
||||||
F3 typeA
|
|
||||||
}
|
|
@ -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 int32
|
|
||||||
}
|
|
@ -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,7 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeA int32
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F typeA
|
|
||||||
}
|
|
@ -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,7 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 int32
|
|
||||||
F2 int32
|
|
||||||
F3 int32
|
|
||||||
}
|
|
@ -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,9 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeA int32
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 typeA
|
|
||||||
F2 typeA
|
|
||||||
F3 typeA
|
|
||||||
}
|
|
@ -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 int64
|
|
||||||
}
|
|
@ -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 map[int32]*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,5 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F map[int32]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,9 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F map[int32]struct {
|
|
||||||
F1 string
|
|
||||||
F2 string
|
|
||||||
F3 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,5 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F map[string]*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,5 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F map[string]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,9 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F map[string]struct {
|
|
||||||
F1 string
|
|
||||||
F2 string
|
|
||||||
F3 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,5 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F *float64
|
|
||||||
}
|
|
@ -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
|
|
||||||
|
|
||||||
type typeA1 float64
|
|
||||||
type typeA2 *float64
|
|
||||||
|
|
||||||
type typeForTest struct {
|
|
||||||
F1 *typeA1
|
|
||||||
F2 typeA2
|
|
||||||
F3 *typeA2
|
|
||||||
}
|
|
@ -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 *int32
|
|
||||||
}
|
|
@ -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)
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user