From b36388035a87c3ee500dc6c9a53adb0de70700ff Mon Sep 17 00:00:00 2001 From: Nick Pillitteri Date: Thu, 29 Feb 2024 13:56:32 -0500 Subject: [PATCH] Allocate map for results to hold expected number of keys Pre-allocate the map used for results based on the number of keys being fetched. Not needing to grow the map as results are added results in a 5-10% performance improvement in local benchmarking. --- memcache/memcache.go | 2 +- memcache/memcache_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/memcache/memcache.go b/memcache/memcache.go index c5962d0..c627cbd 100644 --- a/memcache/memcache.go +++ b/memcache/memcache.go @@ -619,7 +619,7 @@ func (c *Client) GetMulti(keys []string, opts ...Option) (map[string]*Item, erro options := newOptions(opts...) var lk sync.Mutex - m := make(map[string]*Item) + m := make(map[string]*Item, len(keys)) addItemToMap := func(it *Item) { lk.Lock() defer lk.Unlock() diff --git a/memcache/memcache_test.go b/memcache/memcache_test.go index 97f7780..8694066 100644 --- a/memcache/memcache_test.go +++ b/memcache/memcache_test.go @@ -539,6 +539,33 @@ func TestClient_Close_ShouldBeIdempotent(t *testing.T) { c.Close() } +func BenchmarkGetMulti(b *testing.B) { + c := New(testServer) + defer c.Close() + + var keys []string + for i := 0; i < 100; i++ { + key := fmt.Sprintf("bench-%d", i) + keys = append(keys, key) + + err := c.Set(&Item{ + Key: key, + Value: []byte(strings.Repeat("bench payload", 10)), + Flags: 0, + Expiration: 30, + casid: 0, + }) + if err != nil { + b.Fatal("Could not set item for test server: ", err) + } + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _ = c.GetMulti(keys) + } +} + func BenchmarkOnItem(b *testing.B) { fakeServer, err := net.Listen("tcp", "localhost:0") if err != nil {