diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2023-01-26 21:02:56 -0700 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2023-01-30 22:00:25 -0700 |
commit | 2828fa21c0ffd2a32a108b37c0417b01abc42929 (patch) | |
tree | ae671b894fa952e01a410c94fe27e1d0fec37e80 /decode.go | |
parent | 8aa12d3cb043859229810947da6c52e600d34b55 (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.go | 40 |
1 files changed, 20 insertions, 20 deletions
@@ -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 |