summaryrefslogtreecommitdiff
path: root/decode.go
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-01-26 21:02:56 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-01-30 22:00:25 -0700
commit2828fa21c0ffd2a32a108b37c0417b01abc42929 (patch)
treeae671b894fa952e01a410c94fe27e1d0fec37e80 /decode.go
parent8aa12d3cb043859229810947da6c52e600d34b55 (diff)
Avoid doing type switching in inner functions
The CPU profiler tells me that the encoder is spending a lot of time on type switches.
Diffstat (limited to 'decode.go')
-rw-r--r--decode.go40
1 files changed, 20 insertions, 20 deletions
diff --git a/decode.go b/decode.go
index 7ae723c..91be865 100644
--- a/decode.go
+++ b/decode.go
@@ -565,7 +565,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
if dec.disallowUnknownFields {
dec.panicType("", typ, fmt.Errorf("json: unknown field %q", name))
}
- dec.scan(io.Discard)
+ dec.scan(internal.Discard)
return
}
field := index.byPos[idx]
@@ -749,7 +749,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
dec.decode(mValPtr.Elem(), false)
val.Index(i).Set(mValPtr.Elem())
} else {
- dec.scan(io.Discard)
+ dec.scan(internal.Discard)
}
i++
})
@@ -773,18 +773,18 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
}
}
-func (dec *Decoder) scan(out io.Writer) {
+func (dec *Decoder) scan(out internal.RuneWriter) {
limiter := dec.limitingScanner()
for {
c, _, err := limiter.ReadRune()
if err == io.EOF {
return
}
- _, _ = writeRune(out, c)
+ _, _ = out.WriteRune(c)
}
}
-func (dec *Decoder) scanNumber(gTyp reflect.Type, out io.Writer) {
+func (dec *Decoder) scanNumber(gTyp reflect.Type, out internal.RuneWriter) {
if t := dec.peekRuneType(); !t.IsNumber() {
dec.panicType(t.JSONType(), gTyp, nil)
}
@@ -991,34 +991,34 @@ func (dec *Decoder) decodeArray(gTyp reflect.Type, decodeMember func()) {
}
}
-func (dec *Decoder) decodeString(gTyp reflect.Type, out io.Writer) {
+func (dec *Decoder) decodeString(gTyp reflect.Type, out internal.RuneWriter) {
dec.expectRuneType('"', internal.RuneTypeStringBeg, gTyp)
var uhex [4]byte
for {
c, t := dec.readRune()
switch t {
case internal.RuneTypeStringChar:
- _, _ = writeRune(out, c)
+ _, _ = out.WriteRune(c)
case internal.RuneTypeStringEsc, internal.RuneTypeStringEscU:
// do nothing
case internal.RuneTypeStringEsc1:
switch c {
case '"':
- _, _ = writeRune(out, '"')
+ _, _ = out.WriteRune('"')
case '\\':
- _, _ = writeRune(out, '\\')
+ _, _ = out.WriteRune('\\')
case '/':
- _, _ = writeRune(out, '/')
+ _, _ = out.WriteRune('/')
case 'b':
- _, _ = writeRune(out, '\b')
+ _, _ = out.WriteRune('\b')
case 'f':
- _, _ = writeRune(out, '\f')
+ _, _ = out.WriteRune('\f')
case 'n':
- _, _ = writeRune(out, '\n')
+ _, _ = out.WriteRune('\n')
case 'r':
- _, _ = writeRune(out, '\r')
+ _, _ = out.WriteRune('\r')
case 't':
- _, _ = writeRune(out, '\t')
+ _, _ = out.WriteRune('\t')
default:
panic("should not happen")
}
@@ -1038,12 +1038,12 @@ func (dec *Decoder) decodeString(gTyp reflect.Type, out io.Writer) {
handleUnicode:
if utf16.IsSurrogate(c) {
if dec.peekRuneType() != internal.RuneTypeStringEsc {
- _, _ = writeRune(out, utf8.RuneError)
+ _, _ = out.WriteRune(utf8.RuneError)
break
}
dec.expectRune('\\', internal.RuneTypeStringEsc)
if dec.peekRuneType() != internal.RuneTypeStringEscU {
- _, _ = writeRune(out, utf8.RuneError)
+ _, _ = out.WriteRune(utf8.RuneError)
break
}
dec.expectRune('u', internal.RuneTypeStringEscU)
@@ -1063,13 +1063,13 @@ func (dec *Decoder) decodeString(gTyp reflect.Type, out io.Writer) {
rune(uhex[3])<<0
d := utf16.DecodeRune(c, c2)
if d == utf8.RuneError {
- _, _ = writeRune(out, utf8.RuneError)
+ _, _ = out.WriteRune(utf8.RuneError)
c = c2
goto handleUnicode
}
- _, _ = writeRune(out, d)
+ _, _ = out.WriteRune(d)
} else {
- _, _ = writeRune(out, c)
+ _, _ = out.WriteRune(c)
}
case internal.RuneTypeStringEnd:
return