mirror of
https://github.com/hanzoai/metrics.git
synced 2026-10-30 20:03:39 +00:00
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]>
97 lines
2.5 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|