Skip to content

Commit e66fb89

Browse files
authored
Merge pull request #173 from goccy/feature/improve-decoder-interface-performance
Improve decoder performance for empty interface type
2 parents 2dda80b + 4d80b4b commit e66fb89

File tree

1 file changed

+71
-46
lines changed

1 file changed

+71
-46
lines changed

decode_interface.go

Lines changed: 71 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,84 @@ import (
88
)
99

1010
type interfaceDecoder struct {
11-
typ *rtype
12-
structName string
13-
fieldName string
11+
typ *rtype
12+
structName string
13+
fieldName string
14+
sliceDecoder *sliceDecoder
15+
mapDecoder *mapDecoder
16+
floatDecoder *floatDecoder
17+
numberDecoder *numberDecoder
18+
stringDecoder *stringDecoder
19+
}
20+
21+
func newEmptyInterfaceDecoder(structName, fieldName string) *interfaceDecoder {
22+
ifaceDecoder := &interfaceDecoder{
23+
typ: emptyInterfaceType,
24+
structName: structName,
25+
fieldName: fieldName,
26+
floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) {
27+
*(*interface{})(p) = v
28+
}),
29+
numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v Number) {
30+
*(*interface{})(p) = v
31+
}),
32+
stringDecoder: newStringDecoder(structName, fieldName),
33+
}
34+
ifaceDecoder.sliceDecoder = newSliceDecoder(
35+
ifaceDecoder,
36+
emptyInterfaceType,
37+
emptyInterfaceType.Size(),
38+
structName, fieldName,
39+
)
40+
ifaceDecoder.mapDecoder = newMapDecoder(
41+
interfaceMapType,
42+
stringType,
43+
ifaceDecoder.stringDecoder,
44+
interfaceMapType.Elem(),
45+
ifaceDecoder,
46+
structName,
47+
fieldName,
48+
)
49+
return ifaceDecoder
1450
}
1551

1652
func newInterfaceDecoder(typ *rtype, structName, fieldName string) *interfaceDecoder {
53+
emptyIfaceDecoder := newEmptyInterfaceDecoder(structName, fieldName)
54+
stringDecoder := newStringDecoder(structName, fieldName)
1755
return &interfaceDecoder{
1856
typ: typ,
1957
structName: structName,
2058
fieldName: fieldName,
59+
sliceDecoder: newSliceDecoder(
60+
emptyIfaceDecoder,
61+
emptyInterfaceType,
62+
emptyInterfaceType.Size(),
63+
structName, fieldName,
64+
),
65+
mapDecoder: newMapDecoder(
66+
interfaceMapType,
67+
stringType,
68+
stringDecoder,
69+
interfaceMapType.Elem(),
70+
emptyIfaceDecoder,
71+
structName,
72+
fieldName,
73+
),
74+
floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) {
75+
*(*interface{})(p) = v
76+
}),
77+
numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v Number) {
78+
*(*interface{})(p) = v
79+
}),
80+
stringDecoder: stringDecoder,
2181
}
2282
}
2383

2484
func (d *interfaceDecoder) numDecoder(s *stream) decoder {
2585
if s.useNumber {
26-
return newNumberDecoder(d.structName, d.fieldName, func(p unsafe.Pointer, v Number) {
27-
*(*interface{})(p) = v
28-
})
86+
return d.numberDecoder
2987
}
30-
return newFloatDecoder(d.structName, d.fieldName, func(p unsafe.Pointer, v float64) {
31-
*(*interface{})(p) = v
32-
})
88+
return d.floatDecoder
3389
}
3490

3591
var (
@@ -122,29 +178,15 @@ func (d *interfaceDecoder) decodeStreamEmptyInterface(s *stream, depth int64, p
122178
case '{':
123179
var v map[string]interface{}
124180
ptr := unsafe.Pointer(&v)
125-
if err := newMapDecoder(
126-
interfaceMapType,
127-
stringType,
128-
newStringDecoder(d.structName, d.fieldName),
129-
interfaceMapType.Elem(),
130-
newInterfaceDecoder(emptyInterfaceType, d.structName, d.fieldName),
131-
d.structName,
132-
d.fieldName,
133-
).decodeStream(s, depth, ptr); err != nil {
181+
if err := d.mapDecoder.decodeStream(s, depth, ptr); err != nil {
134182
return err
135183
}
136184
*(*interface{})(p) = v
137185
return nil
138186
case '[':
139187
var v []interface{}
140188
ptr := unsafe.Pointer(&v)
141-
if err := newSliceDecoder(
142-
newInterfaceDecoder(emptyInterfaceType, d.structName, d.fieldName),
143-
emptyInterfaceType,
144-
emptyInterfaceType.Size(),
145-
d.structName,
146-
d.fieldName,
147-
).decodeStream(s, depth, ptr); err != nil {
189+
if err := d.sliceDecoder.decodeStream(s, depth, ptr); err != nil {
148190
return err
149191
}
150192
*(*interface{})(p) = v
@@ -308,15 +350,7 @@ func (d *interfaceDecoder) decodeEmptyInterface(buf []byte, cursor, depth int64,
308350
case '{':
309351
var v map[string]interface{}
310352
ptr := unsafe.Pointer(&v)
311-
dec := newMapDecoder(
312-
interfaceMapType,
313-
stringType,
314-
newStringDecoder(d.structName, d.fieldName),
315-
interfaceMapType.Elem(),
316-
newInterfaceDecoder(emptyInterfaceType, d.structName, d.fieldName),
317-
d.structName, d.fieldName,
318-
)
319-
cursor, err := dec.decode(buf, cursor, depth, ptr)
353+
cursor, err := d.mapDecoder.decode(buf, cursor, depth, ptr)
320354
if err != nil {
321355
return 0, err
322356
}
@@ -325,27 +359,18 @@ func (d *interfaceDecoder) decodeEmptyInterface(buf []byte, cursor, depth int64,
325359
case '[':
326360
var v []interface{}
327361
ptr := unsafe.Pointer(&v)
328-
dec := newSliceDecoder(
329-
newInterfaceDecoder(emptyInterfaceType, d.structName, d.fieldName),
330-
emptyInterfaceType,
331-
emptyInterfaceType.Size(),
332-
d.structName, d.fieldName,
333-
)
334-
cursor, err := dec.decode(buf, cursor, depth, ptr)
362+
cursor, err := d.sliceDecoder.decode(buf, cursor, depth, ptr)
335363
if err != nil {
336364
return 0, err
337365
}
338366
**(**interface{})(unsafe.Pointer(&p)) = v
339367
return cursor, nil
340368
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
341-
return newFloatDecoder(d.structName, d.fieldName, func(p unsafe.Pointer, v float64) {
342-
*(*interface{})(p) = v
343-
}).decode(buf, cursor, depth, p)
369+
return d.floatDecoder.decode(buf, cursor, depth, p)
344370
case '"':
345371
var v string
346372
ptr := unsafe.Pointer(&v)
347-
dec := newStringDecoder(d.structName, d.fieldName)
348-
cursor, err := dec.decode(buf, cursor, depth, ptr)
373+
cursor, err := d.stringDecoder.decode(buf, cursor, depth, ptr)
349374
if err != nil {
350375
return 0, err
351376
}

0 commit comments

Comments
 (0)