diff --git a/json/decode.go b/json/decode.go index 46922d5..b44dde6 100644 --- a/json/decode.go +++ b/json/decode.go @@ -1292,15 +1292,19 @@ func (d decoder) decodeInterface(b []byte, p unsafe.Pointer) ([]byte, error) { switch k.Class() { case Object: - v, err = decodeInto[map[string]any](&val, v, d, decoder.decodeMapStringInterface) + m := make(map[string]interface{}) + v, err = d.decodeMapStringInterface(v, unsafe.Pointer(&m)) + val = m case Array: - size := alignedSize(interfaceType) - fn := constructSliceDecodeFunc(size, sliceInterfaceType, decoder.decodeInterface) - v, err = decodeInto[[]any](&val, v, d, fn) + a := make([]interface{}, 0, 10) + v, err = d.decodeSlice(v, unsafe.Pointer(&a), unsafe.Sizeof(a[0]), sliceInterfaceType, decoder.decodeInterface) + val = a case String: - v, err = decodeInto[string](&val, v, d, decoder.decodeString) + s := "" + v, err = d.decodeString(v, unsafe.Pointer(&s)) + val = s case Null: v, val = nil, nil diff --git a/json/golang_bench_test.go b/json/golang_bench_test.go index 201352f..3cf7e5a 100644 --- a/json/golang_bench_test.go +++ b/json/golang_bench_test.go @@ -261,6 +261,32 @@ func BenchmarkUnmarshalString(b *testing.B) { }) } +func BenchmarkUnmarshalObjectMixed(b *testing.B) { + b.ReportAllocs() + data := []byte(`{"string":"hello world","time":"2025-07-17T18:40:04.338Z","bool":true,"integer":42,"decimal":3.14,"null":null,"object":{"hello":"world"},"array":[1,2,3]}`) + b.RunParallel(func(pb *testing.PB) { + var m map[string]any + for pb.Next() { + if err := Unmarshal(data, &m); err != nil { + b.Fatal("Unmarshal:", err) + } + } + }) +} + +func BenchmarkUnmarshalArrayMixed(b *testing.B) { + b.ReportAllocs() + data := []byte(`["hello world","2025-07-17T18:40:04.338Z",true,42,3.14,null,{"hello":"world"},[1,2,3]]`) + b.RunParallel(func(pb *testing.PB) { + var a []any + for pb.Next() { + if err := Unmarshal(data, &a); err != nil { + b.Fatal("Unmarshal:", err) + } + } + }) +} + func BenchmarkUnmarshalFloat64(b *testing.B) { b.ReportAllocs() data := []byte(`3.14`)