diff options
Diffstat (limited to 'src/encoding/json/encode.go')
| -rw-r--r-- | src/encoding/json/encode.go | 32 |
1 files changed, 5 insertions, 27 deletions
diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go index 68512d0225..e7e7c4b7ef 100644 --- a/src/encoding/json/encode.go +++ b/src/encoding/json/encode.go @@ -21,7 +21,6 @@ import ( "strconv" "strings" "sync" - "sync/atomic" "unicode" "unicode/utf8" ) @@ -1258,34 +1257,13 @@ func dominantField(fields []field) (field, bool) { return fields[0], true } -var fieldCache struct { - value atomic.Value // map[reflect.Type][]field - mu sync.Mutex // used only by writers -} +var fieldCache sync.Map // map[reflect.Type][]field // cachedTypeFields is like typeFields but uses a cache to avoid repeated work. func cachedTypeFields(t reflect.Type) []field { - m, _ := fieldCache.value.Load().(map[reflect.Type][]field) - f := m[t] - if f != nil { - return f - } - - // Compute fields without lock. - // Might duplicate effort but won't hold other computations back. - f = typeFields(t) - if f == nil { - f = []field{} + if f, ok := fieldCache.Load(t); ok { + return f.([]field) } - - fieldCache.mu.Lock() - m, _ = fieldCache.value.Load().(map[reflect.Type][]field) - newM := make(map[reflect.Type][]field, len(m)+1) - for k, v := range m { - newM[k] = v - } - newM[t] = f - fieldCache.value.Store(newM) - fieldCache.mu.Unlock() - return f + f, _ := fieldCache.LoadOrStore(t, typeFields(t)) + return f.([]field) } |
