aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <m.shulhan@gmail.com>2022-08-26 21:48:21 +0700
committerShulhan <m.shulhan@gmail.com>2026-04-14 21:51:40 +0700
commit91176a429dea9ca0c5724c45aa07f053de01c7c6 (patch)
tree20aba0253a4fc8db98c1dcbcffd413e39fdec674
parent8c0027ca7bde882aaa063044ac7c64ba5c7a6c92 (diff)
downloadgo-91176a429dea9ca0c5724c45aa07f053de01c7c6.tar.xz
encoding/json: optimize isValidNumber function
Instead of re-slicing the string for checking the value, use single index variable. Benchmark result, name old time/op new time/op delta NumberIsValid-8 19.0ns ± 0% 14.5ns ± 1% -23.70% (p=0.008 n=5+5) name old alloc/op new alloc/op delta NumberIsValid-8 0.00B 0.00B ~ (all equal) name old allocs/op new allocs/op delta NumberIsValid-8 0.00 0.00 ~ (all equal) Change-Id: I4698c5db134998f83ff47fb3add6a04ba6ec3aa0
-rw-r--r--src/encoding/json/encode.go46
1 files changed, 24 insertions, 22 deletions
diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go
index a2f20b8026..5e47413f23 100644
--- a/src/encoding/json/encode.go
+++ b/src/encoding/json/encode.go
@@ -637,14 +637,16 @@ func isValidNumber(s string) bool {
// See https://tools.ietf.org/html/rfc7159#section-6
// and https://www.json.org/img/number.png
- if s == "" {
+ if len(s) == 0 {
return false
}
+ var i int
+
// Optional -
- if s[0] == '-' {
- s = s[1:]
- if s == "" {
+ if s[i] == '-' {
+ i++
+ if len(s) == i {
return false
}
}
@@ -654,41 +656,41 @@ func isValidNumber(s string) bool {
default:
return false
- case s[0] == '0':
- s = s[1:]
+ case s[i] == '0':
+ i++
- case '1' <= s[0] && s[0] <= '9':
- s = s[1:]
- for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
- s = s[1:]
+ case '1' <= s[i] && s[i] <= '9':
+ i++
+ for len(s) > i && '0' <= s[i] && s[i] <= '9' {
+ i++
}
}
// . followed by 1 or more digits.
- if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' {
- s = s[2:]
- for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
- s = s[1:]
+ if len(s)-i >= 2 && s[i] == '.' && '0' <= s[i+1] && s[i+1] <= '9' {
+ i += 2
+ for len(s) > i && '0' <= s[i] && s[i] <= '9' {
+ i++
}
}
// e or E followed by an optional - or + and
// 1 or more digits.
- if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
- s = s[1:]
- if s[0] == '+' || s[0] == '-' {
- s = s[1:]
- if s == "" {
+ if len(s)-i >= 2 && (s[i] == 'e' || s[i] == 'E') {
+ i++
+ if s[i] == '+' || s[i] == '-' {
+ i++
+ if len(s) == i {
return false
}
}
- for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
- s = s[1:]
+ for len(s) > i && '0' <= s[i] && s[i] <= '9' {
+ i++
}
}
// Make sure we are at the end.
- return s == ""
+ return len(s) == i
}
func interfaceEncoder(e *encodeState, v reflect.Value, opts encOpts) {