mirror of https://github.com/goccy/go-json.git
Improve decoder performance for empty interface type
This commit is contained in:
parent
2dda80b368
commit
4d80b4b82c
|
@ -8,28 +8,84 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type interfaceDecoder struct {
|
type interfaceDecoder struct {
|
||||||
typ *rtype
|
typ *rtype
|
||||||
structName string
|
structName string
|
||||||
fieldName string
|
fieldName string
|
||||||
|
sliceDecoder *sliceDecoder
|
||||||
|
mapDecoder *mapDecoder
|
||||||
|
floatDecoder *floatDecoder
|
||||||
|
numberDecoder *numberDecoder
|
||||||
|
stringDecoder *stringDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func newEmptyInterfaceDecoder(structName, fieldName string) *interfaceDecoder {
|
||||||
|
ifaceDecoder := &interfaceDecoder{
|
||||||
|
typ: emptyInterfaceType,
|
||||||
|
structName: structName,
|
||||||
|
fieldName: fieldName,
|
||||||
|
floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) {
|
||||||
|
*(*interface{})(p) = v
|
||||||
|
}),
|
||||||
|
numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v Number) {
|
||||||
|
*(*interface{})(p) = v
|
||||||
|
}),
|
||||||
|
stringDecoder: newStringDecoder(structName, fieldName),
|
||||||
|
}
|
||||||
|
ifaceDecoder.sliceDecoder = newSliceDecoder(
|
||||||
|
ifaceDecoder,
|
||||||
|
emptyInterfaceType,
|
||||||
|
emptyInterfaceType.Size(),
|
||||||
|
structName, fieldName,
|
||||||
|
)
|
||||||
|
ifaceDecoder.mapDecoder = newMapDecoder(
|
||||||
|
interfaceMapType,
|
||||||
|
stringType,
|
||||||
|
ifaceDecoder.stringDecoder,
|
||||||
|
interfaceMapType.Elem(),
|
||||||
|
ifaceDecoder,
|
||||||
|
structName,
|
||||||
|
fieldName,
|
||||||
|
)
|
||||||
|
return ifaceDecoder
|
||||||
}
|
}
|
||||||
|
|
||||||
func newInterfaceDecoder(typ *rtype, structName, fieldName string) *interfaceDecoder {
|
func newInterfaceDecoder(typ *rtype, structName, fieldName string) *interfaceDecoder {
|
||||||
|
emptyIfaceDecoder := newEmptyInterfaceDecoder(structName, fieldName)
|
||||||
|
stringDecoder := newStringDecoder(structName, fieldName)
|
||||||
return &interfaceDecoder{
|
return &interfaceDecoder{
|
||||||
typ: typ,
|
typ: typ,
|
||||||
structName: structName,
|
structName: structName,
|
||||||
fieldName: fieldName,
|
fieldName: fieldName,
|
||||||
|
sliceDecoder: newSliceDecoder(
|
||||||
|
emptyIfaceDecoder,
|
||||||
|
emptyInterfaceType,
|
||||||
|
emptyInterfaceType.Size(),
|
||||||
|
structName, fieldName,
|
||||||
|
),
|
||||||
|
mapDecoder: newMapDecoder(
|
||||||
|
interfaceMapType,
|
||||||
|
stringType,
|
||||||
|
stringDecoder,
|
||||||
|
interfaceMapType.Elem(),
|
||||||
|
emptyIfaceDecoder,
|
||||||
|
structName,
|
||||||
|
fieldName,
|
||||||
|
),
|
||||||
|
floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) {
|
||||||
|
*(*interface{})(p) = v
|
||||||
|
}),
|
||||||
|
numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v Number) {
|
||||||
|
*(*interface{})(p) = v
|
||||||
|
}),
|
||||||
|
stringDecoder: stringDecoder,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *interfaceDecoder) numDecoder(s *stream) decoder {
|
func (d *interfaceDecoder) numDecoder(s *stream) decoder {
|
||||||
if s.useNumber {
|
if s.useNumber {
|
||||||
return newNumberDecoder(d.structName, d.fieldName, func(p unsafe.Pointer, v Number) {
|
return d.numberDecoder
|
||||||
*(*interface{})(p) = v
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return newFloatDecoder(d.structName, d.fieldName, func(p unsafe.Pointer, v float64) {
|
return d.floatDecoder
|
||||||
*(*interface{})(p) = v
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -122,15 +178,7 @@ func (d *interfaceDecoder) decodeStreamEmptyInterface(s *stream, depth int64, p
|
||||||
case '{':
|
case '{':
|
||||||
var v map[string]interface{}
|
var v map[string]interface{}
|
||||||
ptr := unsafe.Pointer(&v)
|
ptr := unsafe.Pointer(&v)
|
||||||
if err := newMapDecoder(
|
if err := d.mapDecoder.decodeStream(s, depth, ptr); err != nil {
|
||||||
interfaceMapType,
|
|
||||||
stringType,
|
|
||||||
newStringDecoder(d.structName, d.fieldName),
|
|
||||||
interfaceMapType.Elem(),
|
|
||||||
newInterfaceDecoder(emptyInterfaceType, d.structName, d.fieldName),
|
|
||||||
d.structName,
|
|
||||||
d.fieldName,
|
|
||||||
).decodeStream(s, depth, ptr); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
*(*interface{})(p) = v
|
*(*interface{})(p) = v
|
||||||
|
@ -138,13 +186,7 @@ func (d *interfaceDecoder) decodeStreamEmptyInterface(s *stream, depth int64, p
|
||||||
case '[':
|
case '[':
|
||||||
var v []interface{}
|
var v []interface{}
|
||||||
ptr := unsafe.Pointer(&v)
|
ptr := unsafe.Pointer(&v)
|
||||||
if err := newSliceDecoder(
|
if err := d.sliceDecoder.decodeStream(s, depth, ptr); err != nil {
|
||||||
newInterfaceDecoder(emptyInterfaceType, d.structName, d.fieldName),
|
|
||||||
emptyInterfaceType,
|
|
||||||
emptyInterfaceType.Size(),
|
|
||||||
d.structName,
|
|
||||||
d.fieldName,
|
|
||||||
).decodeStream(s, depth, ptr); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
*(*interface{})(p) = v
|
*(*interface{})(p) = v
|
||||||
|
@ -308,15 +350,7 @@ func (d *interfaceDecoder) decodeEmptyInterface(buf []byte, cursor, depth int64,
|
||||||
case '{':
|
case '{':
|
||||||
var v map[string]interface{}
|
var v map[string]interface{}
|
||||||
ptr := unsafe.Pointer(&v)
|
ptr := unsafe.Pointer(&v)
|
||||||
dec := newMapDecoder(
|
cursor, err := d.mapDecoder.decode(buf, cursor, depth, ptr)
|
||||||
interfaceMapType,
|
|
||||||
stringType,
|
|
||||||
newStringDecoder(d.structName, d.fieldName),
|
|
||||||
interfaceMapType.Elem(),
|
|
||||||
newInterfaceDecoder(emptyInterfaceType, d.structName, d.fieldName),
|
|
||||||
d.structName, d.fieldName,
|
|
||||||
)
|
|
||||||
cursor, err := dec.decode(buf, cursor, depth, ptr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -325,27 +359,18 @@ func (d *interfaceDecoder) decodeEmptyInterface(buf []byte, cursor, depth int64,
|
||||||
case '[':
|
case '[':
|
||||||
var v []interface{}
|
var v []interface{}
|
||||||
ptr := unsafe.Pointer(&v)
|
ptr := unsafe.Pointer(&v)
|
||||||
dec := newSliceDecoder(
|
cursor, err := d.sliceDecoder.decode(buf, cursor, depth, ptr)
|
||||||
newInterfaceDecoder(emptyInterfaceType, d.structName, d.fieldName),
|
|
||||||
emptyInterfaceType,
|
|
||||||
emptyInterfaceType.Size(),
|
|
||||||
d.structName, d.fieldName,
|
|
||||||
)
|
|
||||||
cursor, err := dec.decode(buf, cursor, depth, ptr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
**(**interface{})(unsafe.Pointer(&p)) = v
|
**(**interface{})(unsafe.Pointer(&p)) = v
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
return newFloatDecoder(d.structName, d.fieldName, func(p unsafe.Pointer, v float64) {
|
return d.floatDecoder.decode(buf, cursor, depth, p)
|
||||||
*(*interface{})(p) = v
|
|
||||||
}).decode(buf, cursor, depth, p)
|
|
||||||
case '"':
|
case '"':
|
||||||
var v string
|
var v string
|
||||||
ptr := unsafe.Pointer(&v)
|
ptr := unsafe.Pointer(&v)
|
||||||
dec := newStringDecoder(d.structName, d.fieldName)
|
cursor, err := d.stringDecoder.decode(buf, cursor, depth, ptr)
|
||||||
cursor, err := dec.decode(buf, cursor, depth, ptr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue