From 3a375f43d39bac7a2646cf1b484eb1835f1ae831 Mon Sep 17 00:00:00 2001 From: phuslu Date: Sat, 30 Dec 2023 20:53:44 +0800 Subject: [PATCH] refine bench tests --- README.md | 24 ++++++------- bench/bench_test.go | 41 +++++++++++++++++++--- bench/memory_test.go | 81 -------------------------------------------- 3 files changed, 48 insertions(+), 98 deletions(-) delete mode 100644 bench/memory_test.go diff --git a/README.md b/README.md index 8a7042f..711663a 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ * Simple - No Dependency - - Less than 1000 Sloc + - Less than 1000 sloc * Fast - Faster than all well-known LRU caches - Zero memory allocs @@ -14,7 +14,7 @@ - Pointerless data structs - Continuous memory layout * Memory efficient - - Save at least 30% memory than other LRU caches + - Uses 24 extra bytes per cache object ### Getting Started @@ -44,23 +44,23 @@ func main() { ### Benchmarks -A Performance result as below +A Performance result on keysize=16, cachesize=1000000, parallelism=32 ``` goos: linux -goarch: amd64 -cpu: Intel(R) Xeon(R) Silver 4216 CPU @ 2.10GHz +goarch: arm64 +pkg: bench BenchmarkCloudflareGet -BenchmarkCloudflareGet-8 100000000 59.11 ns/op 16 B/op 1 allocs/op +BenchmarkCloudflareGet-4 32207244 191.4 ns/op 16 B/op 1 allocs/op BenchmarkCcacheGet -BenchmarkCcacheGet-8 105142296 56.85 ns/op 20 B/op 2 allocs/op +BenchmarkCcacheGet-4 32112368 183.4 ns/op 20 B/op 2 allocs/op BenchmarkRistrettoGet -BenchmarkRistrettoGet-8 131303994 45.99 ns/op 16 B/op 1 allocs/op -BenchmarkGoburrowGet -BenchmarkGoburrowGet-8 100000000 62.94 ns/op 16 B/op 1 allocs/op +BenchmarkRistrettoGet-4 39304964 156.9 ns/op 16 B/op 1 allocs/op +BenchmarkEcacheGet +BenchmarkEcacheGet-4 35331213 166.2 ns/op 0 B/op 0 allocs/op BenchmarkPhusluGet -BenchmarkPhusluGet-8 176671556 34.11 ns/op 0 B/op 0 allocs/op +BenchmarkPhusluGet-4 45333045 132.9 ns/op 0 B/op 0 allocs/op PASS -ok command-line-arguments 43.895s +ok bench 42.942s ``` [godoc-img]: http://img.shields.io/badge/godoc-reference-blue.svg diff --git a/bench/bench_test.go b/bench/bench_test.go index 8ed679d..970bff1 100644 --- a/bench/bench_test.go +++ b/bench/bench_test.go @@ -2,6 +2,7 @@ package bench import ( + "fmt" "testing" "time" _ "unsafe" @@ -14,9 +15,19 @@ import ( ) const ( + keysize = 16 + cachesize = 1000000 parallelism = 32 ) +var keymap = func() (x []string) { + x = make([]string, cachesize) + for i := 0; i < cachesize; i++ { + x[i] = fmt.Sprintf(fmt.Sprintf("%%0%dd", keysize), i) + } + return +}() + //go:noescape //go:linkname fastrandn runtime.fastrandn func fastrandn(x uint32) uint32 @@ -32,7 +43,11 @@ func BenchmarkCloudflareGet(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { - _, _ = cache.Get(keymap[fastrandn(cachesize)]) + i := int(fastrandn(cachesize)) + v, ok := cache.Get(keymap[i]) + if ok && v.(int) != i { + b.Fatalf("get %v from cache want %v, got %v", keymap[i], i, v) + } } }) } @@ -48,7 +63,11 @@ func BenchmarkCcacheGet(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { - _ = cache.Get(keymap[fastrandn(cachesize)]) + i := int(fastrandn(cachesize)) + v := cache.Get(keymap[i]) + if v != nil && v.Value() != i { + b.Fatalf("get %v from cache want %v, got %v", keymap[i], i, v) + } } }) } @@ -68,7 +87,11 @@ func BenchmarkRistrettoGet(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { - _, _ = cache.Get(keymap[fastrandn(cachesize)]) + i := int(fastrandn(cachesize)) + v, ok := cache.Get(keymap[i]) + if ok && v != i { + b.Fatalf("get %v from cache want %v, got %v", keymap[i], i, v) + } } }) } @@ -84,7 +107,11 @@ func BenchmarkEcacheGet(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { - _, _ = cache.Get(keymap[fastrandn(cachesize)]) + i := int(fastrandn(cachesize)) + v, ok := cache.Get(keymap[i]) + if ok && v != i { + b.Fatalf("get %v from cache want %v, got %v", keymap[i], i, v) + } } }) } @@ -100,7 +127,11 @@ func BenchmarkPhusluGet(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { - _, _ = cache.Get(keymap[fastrandn(cachesize)]) + i := int(fastrandn(cachesize)) + v, ok := cache.Get(keymap[i]) + if ok && v != i { + b.Fatalf("get %v from cache want %v, got %v", keymap[i], i, v) + } } }) } diff --git a/bench/memory_test.go b/bench/memory_test.go deleted file mode 100644 index 45bacea..0000000 --- a/bench/memory_test.go +++ /dev/null @@ -1,81 +0,0 @@ -// go test -v -cpu=8 -run=none -bench=. -benchtime=5s -benchmem bench_test.go -package bench - -import ( - "fmt" - "testing" - "time" - - "github.com/DmitriyVTitov/size" - cloudflare "github.com/cloudflare/golibs/lrucache" - ristretto "github.com/dgraph-io/ristretto" - goburrow "github.com/goburrow/cache" - ccache "github.com/karlseguin/ccache/v3" - phuslu "github.com/phuslu/lru" -) - -const ( - keysize = 16 - cachesize = 1_000_000 -) - -var keymap = func() (x []string) { - x = make([]string, cachesize) - for i := 0; i < cachesize; i++ { - x[i] = fmt.Sprintf(fmt.Sprintf("%%0%dd", keysize), i) - } - return -}() - -func TestCloudflareSize(t *testing.T) { - cache := cloudflare.NewMultiLRUCache(1024, cachesize/1024) - for i := 0; i < cachesize; i++ { - cache.Set(keymap[i], i, time.Now().Add(time.Hour)) - } - - t.Logf("cache memory size %v", size.Of(cache)) -} - -func TTestCcacheSize(t *testing.T) { - cache := ccache.New(ccache.Configure[int]().MaxSize(cachesize)) - for i := 0; i < cachesize; i++ { - cache.Set(keymap[i], i, time.Hour) - } - - t.Logf("cache memory size %v", size.Of(cache)) -} - -func TTestRistrettoSize(t *testing.T) { - cache, _ := ristretto.NewCache(&ristretto.Config{ - NumCounters: cachesize, // number of keys to track frequency of (10M). - MaxCost: 1 << 30, // maximum cost of cache (1GB). - BufferItems: 64, // number of keys per Get buffer. - }) - for i := 0; i < cachesize; i++ { - cache.SetWithTTL(keymap[i], i, 1, time.Hour) - } - - t.Logf("cache memory size %v", size.Of(cache)) -} - -func TestGoburrowSize(t *testing.T) { - cache := goburrow.New( - goburrow.WithMaximumSize(cachesize), // Limit number of entries in the cache. - goburrow.WithExpireAfterAccess(time.Hour), // Expire entries after 1 minute since last accessed. - goburrow.WithRefreshAfterWrite(time.Hour), // Expire entries after 2 minutes since last created. - ) - for i := 0; i < cachesize; i++ { - cache.Put(keymap[i], i) - } - - t.Logf("cache memory size %v", size.Of(cache)) -} - -func TestPhusluSize(t *testing.T) { - cache := phuslu.New[string, int](cachesize) - for i := 0; i < cachesize/2; i++ { - cache.SetWithTTL(keymap[i], i, time.Hour) - } - - t.Logf("cache memory size %v", size.Of(cache)) -}