internal/encoding/json: improve decoding of JSON numbers for floats
Per Joe's suggestion, remove producing numberParts when parsing a JSON
number to produce corresponding Value. This saves having to store it
inside Value as well. Only produce numberParts for calls to
Value.{Int,Uint} call.
numberParts is only used for producing integers and removing the logic to
produce numberParts improves overall decoding speed for floats, and shows no
change for integers.
name old time/op new time/op delta
Float-4 559ns ± 0% 288ns ± 0% ~ (p=1.000 n=1+1)
Int-4 471ns ± 0% 466ns ± 0% ~ (p=1.000 n=1+1)
Change-Id: I21bf304ca67dda8d41a4ea0022dcbefd51058c1c
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/168781
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/internal/encoding/json/decode.go b/internal/encoding/json/decode.go
index 452e873..ddf3a68 100644
--- a/internal/encoding/json/decode.go
+++ b/internal/encoding/json/decode.go
@@ -182,11 +182,11 @@
}
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
- num, n := parseNumber(in)
- if num == nil {
+ n, ok := consumeNumber(in)
+ if !ok {
return Value{}, 0, d.newSyntaxError("invalid number %s", errRegexp.Find(in))
}
- return d.newValue(Number, in[:n], num), n, nil
+ return d.newValue(Number, in[:n], nil), n, nil
case '"':
var nerr errors.NonFatal
@@ -308,7 +308,6 @@
typ Type
// value will be set to the following Go type based on the type field:
// Bool => bool
- // Number => *numberParts
// String => string
// Name => string
// It will be nil if none of the above.
@@ -414,8 +413,11 @@
if v.typ != Number {
return "", v.newError("%s is not a number", v.input)
}
- pnum := v.value.(*numberParts)
- num, ok := normalizeToIntString(pnum)
+ parts, ok := parseNumber(v.input)
+ if !ok {
+ return "", v.newError("%s is not a number", v.input)
+ }
+ num, ok := normalizeToIntString(parts)
if !ok {
return "", v.newError("cannot convert %s to integer", v.input)
}