diff --git a/README.md b/README.md index 5225911..2e90b2e 100644 --- a/README.md +++ b/README.md @@ -62,23 +62,23 @@ BenchmarkDecoder_Parallel_Binding_StdLib-16 27582 ns/op 472.5 BenchmarkDecoder_Parallel_Binding_JsonIter-16 13571 ns/op 960.51 MB/s 14685 B/op 385 allocs/op BenchmarkDecoder_Parallel_Binding_GoJson-16 10031 ns/op 1299.51 MB/s 22111 B/op 49 allocs/op -BenchmarkGetOne_Sonic-16 11650 ns/op 1117.81 MB/s 29 B/op 1 allocs/op +BenchmarkGetOne_Sonic-16 3276 ns/op 3975.78 MB/s 24 B/op 1 allocs/op BenchmarkGetOne_Gjson-16 9431 ns/op 1380.81 MB/s 0 B/op 0 allocs/op BenchmarkGetOne_Jsoniter-16 51178 ns/op 254.46 MB/s 27936 B/op 647 allocs/op -BenchmarkGetOne_Parallel_Sonic-16 1955 ns/op 6659.94 MB/s 125 B/op 1 allocs/op +BenchmarkGetOne_Parallel_Sonic-16 216.7 ns/op 60098.95 MB/s 24 B/op 1 allocs/op BenchmarkGetOne_Parallel_Gjson-16 1076 ns/op 12098.62 MB/s 0 B/op 0 allocs/op BenchmarkGetOne_Parallel_Jsoniter-16 17741 ns/op 734.06 MB/s 27945 B/op 647 allocs/op -BenchmarkSetOne_Sonic-16 16124 ns/op 807.70 MB/s 1787 B/op 17 allocs/op +BenchmarkSetOne_Sonic-16 9571 ns/op 1360.61 MB/s 1584 B/op 17 allocs/op BenchmarkSetOne_Sjson-16 36456 ns/op 357.22 MB/s 52180 B/op 9 allocs/op BenchmarkSetOne_Jsoniter-16 79475 ns/op 163.86 MB/s 45862 B/op 964 allocs/op -BenchmarkSetOne_Parallel_Sonic-16 2383 ns/op 5465.02 MB/s 2186 B/op 17 allocs/op +BenchmarkSetOne_Parallel_Sonic-16 850.9 ns/op 15305.31 MB/s 1584 B/op 17 allocs/op BenchmarkSetOne_Parallel_Sjson-16 18194 ns/op 715.77 MB/s 52247 B/op 9 allocs/op BenchmarkSetOne_Parallel_Jsoniter-16 33560 ns/op 388.05 MB/s 45892 B/op 964 allocs/op ``` - [Small](https://github.com/bytedance/sonic/blob/main/testdata/small.go) (400B, 11 keys, 3 layers) -![small benchmarks](bench-small.jpg) +![small benchmarks](bench-small.png) - [Large](https://github.com/bytedance/sonic/blob/main/testdata/twitter.json) (635KB, 10000+ key, 6 layers) -![large benchmarks](bench-large.jpg) +![large benchmarks](bench-large.png) See [bench.sh](https://github.com/bytedance/sonic/blob/main/bench.sh) for benchmark codes. diff --git a/bench-large.jpg b/bench-large.jpg deleted file mode 100644 index a363c08..0000000 Binary files a/bench-large.jpg and /dev/null differ diff --git a/bench-large.png b/bench-large.png new file mode 100644 index 0000000..8a8785e Binary files /dev/null and b/bench-large.png differ diff --git a/bench-small.jpg b/bench-small.jpg deleted file mode 100644 index b663517..0000000 Binary files a/bench-small.jpg and /dev/null differ diff --git a/bench-small.png b/bench-small.png new file mode 100644 index 0000000..7bdab77 Binary files /dev/null and b/bench-small.png differ diff --git a/decoder/decoder.go b/decoder/decoder.go index c81940b..fde6611 100644 --- a/decoder/decoder.go +++ b/decoder/decoder.go @@ -20,7 +20,6 @@ import ( `encoding/json` `reflect` `runtime` - `unsafe` `github.com/bytedance/sonic/internal/native` `github.com/bytedance/sonic/internal/native/types` @@ -96,25 +95,11 @@ func (self *Decoder) Decode(val interface{}) error { if vp == nil || vv.Type.Kind() != reflect.Ptr { return &json.InvalidUnmarshalError{Type: vv.Type.Pack()} } - initalized := (vv.Type.Pack().Elem().Kind() == reflect.Ptr) && (*(*unsafe.Pointer)(vp) != nil) /* create a new stack, and call the decoder */ sb, etp := newStack(), rt.PtrElem(vv.Type) nb, err := decodeTypedPointer(self.s, self.i, etp, vp, sb, self.f) - if err != nil { - // clear val memory when decode failed, - // not including MismatcheTypeError - if _, ok := err.(*MismatchTypeError); !ok { - ev := reflect.ValueOf(val).Elem() - if initalized { - ev.Elem().Set(reflect.Zero(ev.Elem().Type())) - } else { - ev.Set(reflect.Zero(ev.Type())) - } - } - } - /* return the stack back */ self.i = nb freeStack(sb) diff --git a/decoder/decoder_test.go b/decoder/decoder_test.go index 58c1e3c..4d95cf2 100644 --- a/decoder/decoder_test.go +++ b/decoder/decoder_test.go @@ -169,86 +169,6 @@ func TestSkipMismatchTypeError(t *testing.T) { }) } -type testStruct struct { - A int `json:"a"` - B string `json:"b"` -} - -func TestClearMemWhenError(t *testing.T) { - var data = `{"a":1,"b":"1"]` - var v, v2 testStruct - _, err := decode(data, &v, false) - err2 := json.Unmarshal([]byte(data), &v2) - assert.Equal(t, err2 == nil, err == nil) - assert.Equal(t, v2, v) - - var z, z2 = new(testStruct), new(testStruct) - _, err = decode(data, z, false) - err2 = json.Unmarshal([]byte(data), z2) - assert.Equal(t, err2 == nil, err == nil) - assert.Equal(t, z2, z) - - var y, y2 *testStruct - _, err = decode(data, &y, false) - err2 = json.Unmarshal([]byte(data), &y2) - assert.Equal(t, err2 == nil, err == nil) - assert.Equal(t, y2, y) - - var x, x2 = new(testStruct), new(testStruct) - _, err = decode(data, &x, false) - err2 = json.Unmarshal([]byte(data), &x2) - assert.Equal(t, err2 == nil, err == nil) - assert.Equal(t, x2, x) - - var a, a2 interface{} - _, err = decode(data, &a, false) - err2 = json.Unmarshal([]byte(data), &a2) - assert.Equal(t, err2 == nil, err == nil) - assert.Equal(t, a2, a) - - var b, b2 = new(interface{}), new(interface{}) - _, err = decode(data, b, false) - err2 = json.Unmarshal([]byte(data), b2) - assert.Equal(t, err2 == nil, err == nil) - assert.Equal(t, b2, b) - - var c, c2 *interface{} - _, err = decode(data, &c, false) - err2 = json.Unmarshal([]byte(data), &c2) - assert.Equal(t, err2 == nil, err == nil) - assert.Equal(t, c2, c) - - var d, d2 = new(interface{}), new(interface{}) - _, err = decode(data, &d, false) - err2 = json.Unmarshal([]byte(data), &d2) - assert.Equal(t, err2 == nil, err == nil) - assert.Equal(t, d2, d) - - var e, e2 map[string]interface{} - _, err = decode(data, &e, false) - err2 = json.Unmarshal([]byte(data), &e2) - assert.Equal(t, err2 == nil, err == nil) - assert.Equal(t, e2, e) - - var f, f2 = new(map[string]interface{}), new(map[string]interface{}) - _, err = decode(data, &f, false) - err2 = json.Unmarshal([]byte(data), &f2) - assert.Equal(t, err2 == nil, err == nil) - assert.Equal(t, f2, f) - - var g, g2 = new(map[string]interface{}), new(map[string]interface{}) - _, err = decode(data, g, false) - err2 = json.Unmarshal([]byte(data), g2) - assert.Equal(t, err2 == nil, err == nil) - assert.Equal(t, g2, g) - - var h, h2 *map[string]interface{} - _, err = decode(data, &h, false) - err2 = json.Unmarshal([]byte(data), &h2) - assert.Equal(t, err2 == nil, err == nil) - assert.Equal(t, h2, h) -} - func TestDecodeCorrupt(t *testing.T) { var ds = []string{ `{,}`,