diff options
| author | Shulhan <m.shulhan@gmail.com> | 2022-08-26 21:48:21 +0700 |
|---|---|---|
| committer | Shulhan <m.shulhan@gmail.com> | 2026-04-14 21:51:40 +0700 |
| commit | 91176a429dea9ca0c5724c45aa07f053de01c7c6 (patch) | |
| tree | 20aba0253a4fc8db98c1dcbcffd413e39fdec674 /src/encoding/json | |
| parent | 8c0027ca7bde882aaa063044ac7c64ba5c7a6c92 (diff) | |
| download | go-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
Diffstat (limited to 'src/encoding/json')
| -rw-r--r-- | src/encoding/json/encode.go | 46 |
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) { |
