| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | package metrix |
| 4 | |
| 5 | import ( |
| 6 | "fmt" |
| 7 | "testing" |
| 8 | ) |
| 9 | |
| 10 | // Baseline results (to be updated before/after hot-path refactors): |
| 11 | // Command: |
| 12 | // |
| 13 | // go test ./pkg/metrix -run '^$' -bench 'RuntimeStoreSingleWriteAtCardinality|CollectorCommitSparseAtCardinality' -benchmem |
| 14 | // |
| 15 | // BenchmarkRuntimeStoreSingleWriteAtCardinality/series_1-14 3574240 318.1 ns/op 696 B/op 8 allocs/op |
| 16 | // BenchmarkRuntimeStoreSingleWriteAtCardinality/series_10-14 2242100 536.9 ns/op 944 B/op 10 allocs/op |
| 17 | // BenchmarkRuntimeStoreSingleWriteAtCardinality/series_100-14 499005 2421 ns/op 3984 B/op 10 allocs/op |
| 18 | // BenchmarkRuntimeStoreSingleWriteAtCardinality/series_1000-14 46905 25925 ns/op 55096 B/op 12 allocs/op |
| 19 | // BenchmarkCollectorCommitSparseAtCardinality/series_100_touched_5-14 710890 1664 ns/op 3864 B/op 49 allocs/op |
| 20 | // BenchmarkCollectorCommitSparseAtCardinality/series_1000_touched_5-14 628440 1741 ns/op 3870 B/op 49 allocs/op |
| 21 | // BenchmarkCollectorCommitSparseAtCardinality/series_5000_touched_10-14 279890 4242 ns/op 7205 B/op 85 allocs/op |
| 22 | // |
| 23 | // After runtime overlay+collector clone-on-modify changes (2026-02-19): |
| 24 | // |
| 25 | // BenchmarkRuntimeStoreSingleWriteAtCardinality/series_1-14 4073148 294.3 ns/op 726 B/op 8 allocs/op |
| 26 | // BenchmarkRuntimeStoreSingleWriteAtCardinality/series_10-14 3756022 297.6 ns/op 729 B/op 8 allocs/op |
| 27 | // BenchmarkRuntimeStoreSingleWriteAtCardinality/series_100-14 3635368 331.2 ns/op 777 B/op 8 allocs/op |
| 28 | // BenchmarkRuntimeStoreSingleWriteAtCardinality/series_1000-14 1550416 730.2 ns/op 1575 B/op 8 allocs/op |
| 29 | // BenchmarkCollectorCommitSparseAtCardinality/series_100_touched_5-14 667111 1787 ns/op 3880 B/op 49 allocs/op |
| 30 | // BenchmarkCollectorCommitSparseAtCardinality/series_1000_touched_5-14 615114 1858 ns/op 3881 B/op 49 allocs/op |
| 31 | // BenchmarkCollectorCommitSparseAtCardinality/series_5000_touched_10-14 240637 4481 ns/op 7166 B/op 85 allocs/op |
| 32 | // |
| 33 | // After collector work-elimination slice (1A + 2B + 3B) (2026-02-19): |
| 34 | // |
| 35 | // BenchmarkCollectorCommitSparseAtCardinality/series_50000_touched_10-14 978680 2471 ns/op 5697 B/op 45 allocs/op |
| 36 | // BenchmarkCollectorCommitSparseAtCardinality/series_100000_touched_20-14 511872 4346 ns/op 11316 B/op 77 allocs/op |
| 37 | func BenchmarkRuntimeStoreSingleWriteAtCardinality(b *testing.B) { |
| 38 | tests := map[string]struct { |
| 39 | totalSeries int |
| 40 | }{ |
| 41 | "series_1": {totalSeries: 1}, |
| 42 | "series_10": {totalSeries: 10}, |
| 43 | "series_100": {totalSeries: 100}, |
| 44 | "series_1000": {totalSeries: 1000}, |
| 45 | } |
| 46 | |
| 47 | for name, tc := range tests { |
| 48 | b.Run(name, func(b *testing.B) { |
| 49 | s := NewRuntimeStore() |
| 50 | gv := s.Write().StatefulMeter("runtime.hotpath").Vec("id").Gauge("value") |
| 51 | |
| 52 | for i := 0; i < tc.totalSeries; i++ { |
| 53 | h, err := gv.GetWithLabelValues(fmt.Sprintf("s%d", i)) |
| 54 | if err != nil { |
| 55 | b.Fatalf("prepopulate handle: %v", err) |
| 56 | } |
| 57 | h.Set(SampleValue(i)) |
| 58 | } |
| 59 | |
| 60 | hot, err := gv.GetWithLabelValues("s0") |
| 61 | if err != nil { |
| 62 | b.Fatalf("hot handle: %v", err) |
| 63 | } |
| 64 | |
| 65 | b.ReportAllocs() |
| 66 | b.ResetTimer() |
| 67 | for i := 0; i < b.N; i++ { |
| 68 | hot.Set(SampleValue(i)) |
| 69 | } |
| 70 | }) |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | func BenchmarkCollectorCommitSparseAtCardinality(b *testing.B) { |
| 75 | tests := map[string]struct { |
| 76 | totalSeries int |
| 77 | touched int |
| 78 | }{ |
| 79 | "series_100_touched_5": {totalSeries: 100, touched: 5}, |
| 80 | "series_1000_touched_5": {totalSeries: 1000, touched: 5}, |
| 81 | "series_5000_touched_10": {totalSeries: 5000, touched: 10}, |
| 82 | "series_50000_touched_10": {totalSeries: 50000, touched: 10}, |
| 83 | "series_100000_touched_20": {totalSeries: 100000, touched: 20}, |
| 84 | } |
| 85 | |
| 86 | for name, tc := range tests { |
| 87 | b.Run(name, func(b *testing.B) { |
| 88 | s := NewCollectorStore() |
| 89 | cc := benchmarkCycleController(b, s) |
| 90 | gv := s.Write().SnapshotMeter("collect.hotpath").Vec("id").Gauge("value") |
| 91 | |
| 92 | all := make([]SnapshotGauge, 0, tc.totalSeries) |
| 93 | for i := 0; i < tc.totalSeries; i++ { |
| 94 | h, err := gv.GetWithLabelValues(fmt.Sprintf("s%d", i)) |
| 95 | if err != nil { |
| 96 | b.Fatalf("prepopulate handle: %v", err) |
| 97 | } |
| 98 | all = append(all, h) |
| 99 | } |
| 100 | |
| 101 | // Create committed baseline cardinality. |
| 102 | cc.BeginCycle() |
| 103 | for i, h := range all { |
| 104 | h.Observe(SampleValue(i)) |
| 105 | } |
| 106 | cc.CommitCycleSuccess() |
| 107 | |
| 108 | hot := all[:tc.touched] |
| 109 | b.ReportAllocs() |
| 110 | b.ResetTimer() |
| 111 | for i := 0; i < b.N; i++ { |
| 112 | cc.BeginCycle() |
| 113 | for j, h := range hot { |
| 114 | h.Observe(SampleValue(i + j)) |
| 115 | } |
| 116 | cc.CommitCycleSuccess() |
| 117 | } |
| 118 | }) |
| 119 | } |
| 120 | } |