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/bench_test.go b/internal/encoding/json/bench_test.go
new file mode 100644
index 0000000..4db8af9
--- /dev/null
+++ b/internal/encoding/json/bench_test.go
@@ -0,0 +1,41 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package json_test
+
+import (
+ "testing"
+
+ "github.com/golang/protobuf/v2/internal/encoding/json"
+)
+
+func BenchmarkFloat(b *testing.B) {
+ input := []byte("1.797693134862315708145274237317043567981e+308")
+ for i := 0; i < b.N; i++ {
+ dec := json.NewDecoder(input)
+ val, err := dec.Read()
+ if err != nil {
+ b.Fatal(err)
+ }
+ _, err = val.Float(64)
+ if err != nil {
+ b.Fatal(err)
+ }
+ }
+}
+
+func BenchmarkInt(b *testing.B) {
+ input := []byte("922337203.6854775807e+10")
+ for i := 0; i < b.N; i++ {
+ dec := json.NewDecoder(input)
+ val, err := dec.Read()
+ if err != nil {
+ b.Fatal(err)
+ }
+ _, err = val.Int(64)
+ if err != nil {
+ b.Fatal(err)
+ }
+ }
+}