mirror of
https://github.com/gohugoio/hugo.git
synced 2025-04-26 13:40:38 +03:00
common/hreflect: Replace the map/RWMutex method cache with sync.Map
It's much faster when running in parallel: ``` GetMethodByName-10 125.1n ± 6% 181.7n ± 7% +45.30% (p=0.002 n=6) GetMethodByNamePara-10 770.10n ± 1% 24.77n ± 9% -96.78% (p=0.002 n=6) ```
This commit is contained in:
parent
26d986fc0d
commit
8d2379bcb3
2 changed files with 19 additions and 16 deletions
|
@ -134,12 +134,7 @@ type methodKey struct {
|
|||
name string
|
||||
}
|
||||
|
||||
type methods struct {
|
||||
sync.RWMutex
|
||||
cache map[methodKey]int
|
||||
}
|
||||
|
||||
var methodCache = &methods{cache: make(map[methodKey]int)}
|
||||
var methodCache sync.Map
|
||||
|
||||
// GetMethodByName is the same as reflect.Value.MethodByName, but it caches the
|
||||
// type lookup.
|
||||
|
@ -157,22 +152,16 @@ func GetMethodByName(v reflect.Value, name string) reflect.Value {
|
|||
// -1 if no such method exists.
|
||||
func GetMethodIndexByName(tp reflect.Type, name string) int {
|
||||
k := methodKey{tp, name}
|
||||
methodCache.RLock()
|
||||
index, found := methodCache.cache[k]
|
||||
methodCache.RUnlock()
|
||||
v, found := methodCache.Load(k)
|
||||
if found {
|
||||
return index
|
||||
return v.(int)
|
||||
}
|
||||
|
||||
methodCache.Lock()
|
||||
defer methodCache.Unlock()
|
||||
|
||||
m, ok := tp.MethodByName(name)
|
||||
index = m.Index
|
||||
index := m.Index
|
||||
if !ok {
|
||||
index = -1
|
||||
}
|
||||
methodCache.cache[k] = index
|
||||
methodCache.Store(k, index)
|
||||
|
||||
if !ok {
|
||||
return -1
|
||||
|
|
|
@ -134,3 +134,17 @@ func BenchmarkGetMethodByName(b *testing.B) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetMethodByNamePara(b *testing.B) {
|
||||
v := reflect.ValueOf(&testStruct{})
|
||||
methods := []string{"Method1", "Method2", "Method3", "Method4", "Method5"}
|
||||
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
for _, method := range methods {
|
||||
_ = GetMethodByName(v, method)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue