Skip to content

Commit

Permalink
expvar: improve Map.addKey for large number of keys
Browse files Browse the repository at this point in the history
The existing implementation has poor performance for large number of
keys because it chooses to append the new key to the sorted keys array
and sort the new array again.

The improvement tries to utilize the sorted keys array by searching the
index and doing an insertion if any. It also fixes an error that
duplicate keys may be inserted in high concurrent scenes.

Fixes #31414
  • Loading branch information
ShiKaiWi committed Apr 11, 2019
1 parent 3cb92fc commit 202ddc1
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/expvar/expvar.go
Expand Up @@ -141,8 +141,14 @@ func (v *Map) Init() *Map {
func (v *Map) addKey(key string) {
v.keysMu.Lock()
defer v.keysMu.Unlock()
v.keys = append(v.keys, key)
sort.Strings(v.keys)

if i := sort.SearchStrings(v.keys, key); i >= len(v.keys) {
v.keys = append(v.keys, key)
} else if v.keys[i] != key {
v.keys = append(v.keys, "")
copy(v.keys[i+1:], v.keys[i:len(v.keys)-1])
v.keys[i] = key
}
}

func (v *Map) Get(key string) Var {
Expand Down
27 changes: 27 additions & 0 deletions src/expvar/expvar_test.go
Expand Up @@ -8,6 +8,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"math/rand"
"net"
"net/http/httptest"
"reflect"
Expand Down Expand Up @@ -350,6 +351,32 @@ func BenchmarkMapAddDifferent(b *testing.B) {
})
}

func BenchmarkMapAddDifferentRandom(b *testing.B) {
procKeys := make([][]string, runtime.GOMAXPROCS(0))
for i := range procKeys {
keys := make([]string, 100)
for j := range keys {
keys[j] = fmt.Sprint(i, rand.Int())
}
procKeys[i] = keys
}

b.ResetTimer()

var n int32
b.RunParallel(func(pb *testing.PB) {
i := int(atomic.AddInt32(&n, 1)-1) % len(procKeys)
keys := procKeys[i]

for pb.Next() {
m := new(Map).Init()
for _, k := range keys {
m.Add(k, 1)
}
}
})
}

func BenchmarkMapAddSameSteadyState(b *testing.B) {
m := new(Map).Init()
b.RunParallel(func(pb *testing.PB) {
Expand Down

0 comments on commit 202ddc1

Please sign in to comment.