aboutsummaryrefslogtreecommitdiff
path: root/internal/cache/clock/bench_test.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-06-09 05:15:58 +0000
committerGravatar Runxi Yu2026-06-09 05:15:58 +0000
commit55676a35757bcbf2fa40cc3fd144ba412c65b658 (patch)
tree4c75c8497941d7b8c8c5530f5467bf42610c3f10 /internal/cache/clock/bench_test.go
parentinternal/lru: Add sharded CLOCK (diff)
signatureNo signature
internal/cache: add (and move clock to internal/cache/clock)
Diffstat (limited to 'internal/cache/clock/bench_test.go')
-rw-r--r--internal/cache/clock/bench_test.go109
1 files changed, 109 insertions, 0 deletions
diff --git a/internal/cache/clock/bench_test.go b/internal/cache/clock/bench_test.go
new file mode 100644
index 00000000..49d85cde
--- /dev/null
+++ b/internal/cache/clock/bench_test.go
@@ -0,0 +1,109 @@
+package clock //nolint:testpackage
+
+import (
+ "sync/atomic"
+ "testing"
+)
+
+func benchWeight(_, _ int) uint64 { return 1 }
+
+// goroutineSeq hands each parallel worker a distinct starting offset
+// so workers don't go in lockstep over identical keys.
+var goroutineSeq atomic.Uint64
+
+func workerOffset() int {
+ return int(goroutineSeq.Add(1) * 0x9E3779B1)
+}
+
+func BenchmarkReadHeavy(b *testing.B) {
+ // ≈95% Get hits, ≈5% Add, and fits budget.
+
+ const n = 100_000
+
+ cache := New(n, benchWeight)
+ for k := range n {
+ cache.Add(k, k)
+ }
+
+ b.ResetTimer()
+ b.RunParallel(func(pb *testing.PB) {
+ i := workerOffset()
+ for pb.Next() {
+ i++
+ key := i % n
+ if i%20 == 0 {
+ cache.Add(key, key)
+ } else {
+ _, _ = cache.Get(key)
+ }
+ }
+ })
+}
+
+func BenchmarkHotKey(b *testing.B) {
+ // Every worker does Get over a relatively small hot set.
+
+ const (
+ hot = 64
+ maxWeight = 4096
+ )
+
+ cache := New(maxWeight, benchWeight)
+ for k := range hot {
+ cache.Add(k, k)
+ }
+
+ b.ResetTimer()
+ b.RunParallel(func(pb *testing.PB) {
+ i := workerOffset()
+ for pb.Next() {
+ i++
+ _, _ = cache.Get(i % hot)
+ }
+ })
+}
+
+func BenchmarkMixed(b *testing.B) {
+ // Even split of Get and Add over a working set that fits.
+
+ const n = 100_000
+
+ cache := New(n, benchWeight)
+ for k := range n {
+ cache.Add(k, k)
+ }
+
+ b.ResetTimer()
+ b.RunParallel(func(pb *testing.PB) {
+ i := workerOffset()
+ for pb.Next() {
+ i++
+ key := i % n
+ if i%2 == 0 {
+ cache.Add(key, key)
+ } else {
+ _, _ = cache.Get(key)
+ }
+ }
+ })
+}
+
+func BenchmarkChurn(b *testing.B) {
+ // Every op inserts a fresh key into a small budget.
+ // I don't think this is likely to happen for git delta caches,
+ // but this may matter if we use this for other workloads later.
+
+ const maxWeight = 4096
+
+ cache := New(maxWeight, benchWeight)
+
+ b.ResetTimer()
+ b.RunParallel(func(pb *testing.PB) {
+ base := workerOffset()
+ i := 0
+ for pb.Next() {
+ i++
+ cache.Add(base+i, i)
+ }
+ })
+}