Files
metrics/lib/storage/metric_id_cache_timing_test.go
Artem FetishevandGitHub 0a1c4b22b6 lib/storage: metricIDCache cache follow-up for a357901d8d (#10468) (#10479)
This is a follow-up PR for a357901d8d (#10468):

- Extract the bucket size into a constant and document it
- Make benchmark constant metricIDCache-specific
- Add the same benchmark for dateMetricIDCache to compare it with metricIDCache.  See https://github.com/VictoriaMetrics/VictoriaMetrics/pull/10479 for benchmark results.

Signed-off-by: Artem Fetishev <[email protected]>
2026-02-17 16:10:32 +01:00

97 lines
2.5 KiB
Go

package storage
import (
"fmt"
"math/rand"
"testing"
"time"
)
type benchMetricIDCacheState int
const (
benchMetricIDCacheStateCold benchMetricIDCacheState = iota
benchMetricIDCacheStateWarm
benchMetricIDCacheStateRotated
)
var benchMetricIDCacheStates = [...]benchMetricIDCacheState{
benchMetricIDCacheStateCold,
benchMetricIDCacheStateWarm,
benchMetricIDCacheStateRotated,
}
func (s benchMetricIDCacheState) String() string {
return [...]string{" cold", " warm", "rotated"}[s]
}
func BenchmarkMetricIDCache_Has(b *testing.B) {
f := func(b *testing.B, numMetricIDs, distance int64, hitsOnly bool, state benchMetricIDCacheState) {
b.Helper()
c := newMetricIDCache()
defer c.MustStop()
warmUp := state == benchMetricIDCacheStateWarm || state == benchMetricIDCacheStateRotated
rotate := state == benchMetricIDCacheStateRotated
metricIDMin := time.Now().UnixNano()
metricIDMax := metricIDMin + numMetricIDs*distance
for metricID := metricIDMin; metricID <= metricIDMax; metricID += distance {
c.Set(uint64(metricID))
if warmUp && !c.Has(uint64(metricID)) {
b.Fatalf("metricID not in cache: %d", metricID)
}
}
if rotate {
c.shards[rand.Intn(metricIDCacheShardCount)].rotate()
}
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
if hitsOnly {
metricID := metricIDMin + rand.Int63n(numMetricIDs)*distance
for pb.Next() {
if !c.Has(uint64(metricID)) {
b.Fatalf("metricID not in cache: %d", metricID)
}
metricID += distance
if metricID > metricIDMax {
metricID = metricIDMin
}
}
} else {
// misses only
metricID := metricIDMax + distance
for pb.Next() {
if c.Has(uint64(metricID)) {
b.Fatalf("metricID is in cache: %d", metricID)
}
metricID += distance
}
}
})
b.ReportAllocs()
b.ReportMetric(float64(c.Stats().SizeBytes), "sizeBytes")
}
subB := func(numMetricIDs, distance int64, hitsOnly bool, state benchMetricIDCacheState) {
hitsOrMisses := " hits-only"
if !hitsOnly {
hitsOrMisses = "misses-only"
}
name := fmt.Sprintf("%s/%s/n%d/d%d", hitsOrMisses, state, numMetricIDs, distance)
b.Run(name, func(b *testing.B) {
f(b, numMetricIDs, distance, hitsOnly, state)
})
}
for _, hitsOnly := range []bool{true, false} {
for _, state := range benchMetricIDCacheStates {
for _, numMetricIDs := range []int64{100_000, 1_000_000, 10_000_000} {
for _, distance := range []int64{1, 10, 100} {
subB(numMetricIDs, distance, hitsOnly, state)
}
}
}
}
}