mirror of
https://github.com/json-iterator/go.git
synced 2025-04-01 21:24:21 +02:00
the unit test uses compatible mode. The benchmarks measure compat, default, and fastest. This still fails for strings and slices and maps all over the place.
140 lines
3.5 KiB
Go
140 lines
3.5 KiB
Go
package test
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"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 < 1000; i++ {
|
|
var before T
|
|
fz.Fuzz(&before)
|
|
|
|
jbStd, err := json.Marshal(before)
|
|
if err != nil {
|
|
t.Errorf("failed to marshal with stdlib: %v", err)
|
|
}
|
|
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
if err != nil {
|
|
t.Errorf("failed to marshal with jsoniter: %v", err)
|
|
}
|
|
if string(jbStd) != string(jbIter) {
|
|
t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
}
|
|
|
|
var afterStd T
|
|
err = json.Unmarshal(jbIter, &afterStd)
|
|
if err != nil {
|
|
t.Errorf("failed to unmarshal with stdlib: %v", err)
|
|
}
|
|
var afterIter T
|
|
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
|
|
if err != nil {
|
|
t.Errorf("failed to unmarshal with jsoniter: %v", err)
|
|
}
|
|
if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
t.Errorf("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
|
|
json.Indent(&buf, src, prefix, indentStr)
|
|
return buf.String()
|
|
}
|
|
|
|
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
|
|
t.ReportAllocs()
|
|
t.ResetTimer()
|
|
|
|
var obj T
|
|
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 T
|
|
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 T
|
|
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)
|
|
}
|