summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-01-26 13:59:35 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-01-30 22:00:25 -0700
commit8aa12d3cb043859229810947da6c52e600d34b55 (patch)
tree4b7b3a8e9adafbbb06531ef3c06fb200d42abd32
parent005dfe26e308b965c2f42c81d34a4b48757414a3 (diff)
struct.go: Cache structIndexes
This should help save some CPU time and avoid some memory churn.
-rw-r--r--go.mod5
-rw-r--r--go.sum2
-rw-r--r--struct.go14
3 files changed, 19 insertions, 2 deletions
diff --git a/go.mod b/go.mod
index 74386a3..452d2ff 100644
--- a/go.mod
+++ b/go.mod
@@ -2,7 +2,10 @@ module git.lukeshu.com/go/lowmemjson
go 1.18
-require github.com/stretchr/testify v1.8.0
+require (
+ git.lukeshu.com/go/typedsync v0.0.0-20230126205501-1e8afc0ceb1e
+ github.com/stretchr/testify v1.8.0
+)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
diff --git a/go.sum b/go.sum
index 5164829..76cf271 100644
--- a/go.sum
+++ b/go.sum
@@ -1,3 +1,5 @@
+git.lukeshu.com/go/typedsync v0.0.0-20230126205501-1e8afc0ceb1e h1:ZAzzElMx7aMgJXC9QXOxIPyoZrWxX00eP2sR4UHYP+4=
+git.lukeshu.com/go/typedsync v0.0.0-20230126205501-1e8afc0ceb1e/go.mod h1:EAn7NcfoGeGMv3DWxKQnifcT/rYPAIEqp9Rsz//oYqY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
diff --git a/struct.go b/struct.go
index b7fc287..8a664c6 100644
--- a/struct.go
+++ b/struct.go
@@ -7,6 +7,8 @@ package lowmemjson
import (
"reflect"
+ "git.lukeshu.com/go/typedsync"
+
"git.lukeshu.com/go/lowmemjson/internal"
)
@@ -25,9 +27,19 @@ type structIndex struct {
byName map[string]int
}
+var structIndexCache typedsync.CacheMap[reflect.Type, structIndex]
+
// indexStruct takes a struct Type, and indexes its fields for use by
-// Decoder.Decode() and Encoder.Encode().
+// Decoder.Decode() and Encoder.Encode(). indexStruct caches its
+// results.
func indexStruct(typ reflect.Type) structIndex {
+ ret, _ := structIndexCache.LoadOrCompute(typ, indexStructReal)
+ return ret
+}
+
+// indexStructReal is like indexStruct, but is the real indexer,
+// bypassing the cache.
+func indexStructReal(typ reflect.Type) structIndex {
var byPos []structField
byName := make(map[string][]int)