Skip to content

Commit da12a0d

Browse files
committed
Add benchmarks
1 parent b7b0558 commit da12a0d

File tree

3 files changed

+115
-1
lines changed

3 files changed

+115
-1
lines changed

pkg/collector/distinct_string_collector_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package collector
22

33
import (
44
"fmt"
5+
"strconv"
56
"sync"
67
"testing"
78

@@ -53,3 +54,54 @@ func TestDistinctStringCollectorIsSafe(t *testing.T) {
5354
require.Equal(t, len(d.Strings()), 10*100)
5455
require.False(t, d.Exceeded())
5556
}
57+
58+
func BenchmarkDistinctStringCollect(b *testing.B) {
59+
// simulate 100 ingesters, each returning 10_000 tag values
60+
numIngesters := 100
61+
numTagValuesPerIngester := 10_000
62+
ingesterStrings := make([][]string, numIngesters)
63+
for i := 0; i < numIngesters; i++ {
64+
strings := make([]string, numTagValuesPerIngester)
65+
for j := 0; j < numTagValuesPerIngester; j++ {
66+
strings[j] = fmt.Sprintf("string_%d_%d", i, j)
67+
}
68+
ingesterStrings[i] = strings
69+
}
70+
71+
limits := []int{
72+
0, // no limit
73+
100_000, // 100KB
74+
1_000_000, // 1MB
75+
10_000_000, // 10MB
76+
}
77+
78+
b.ResetTimer() // to exclude the setup time for generating tag values
79+
for _, lim := range limits {
80+
b.Run("uniques_limit:"+strconv.Itoa(lim), func(b *testing.B) {
81+
for n := 0; n < b.N; n++ {
82+
distinctStrings := NewDistinctString(lim)
83+
for _, values := range ingesterStrings {
84+
for _, v := range values {
85+
if distinctStrings.Collect(v) {
86+
break // stop early if limit is reached
87+
}
88+
}
89+
}
90+
}
91+
})
92+
93+
b.Run("duplicates_limit:"+strconv.Itoa(lim), func(b *testing.B) {
94+
for n := 0; n < b.N; n++ {
95+
distinctStrings := NewDistinctString(lim)
96+
for i := 0; i < numIngesters; i++ {
97+
for j := 0; j < numTagValuesPerIngester; j++ {
98+
// collect first item to simulate duplicates
99+
if distinctStrings.Collect(ingesterStrings[i][0]) {
100+
break // stop early if limit is reached
101+
}
102+
}
103+
}
104+
}
105+
})
106+
}
107+
}

pkg/collector/scoped_distinct_string.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package collector
22

3-
import "sync"
3+
import (
4+
"sync"
5+
)
46

57
type ScopedDistinctString struct {
68
cols map[string]*DistinctString

pkg/collector/scoped_distinct_string_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package collector
33
import (
44
"fmt"
55
"slices"
6+
"strconv"
67
"sync"
78
"testing"
89

@@ -148,3 +149,62 @@ func TestScopedDistinctStringCollectorIsSafe(t *testing.T) {
148149
require.Equal(t, totalStrings, 10*100)
149150
require.False(t, d.Exceeded())
150151
}
152+
153+
func BenchmarkScopedDistinctStringCollect(b *testing.B) {
154+
// simulate 100 ingesters, each returning 10_000 tags with various scopes
155+
numIngesters := 100
156+
numTagsPerIngester := 10_000
157+
ingesterTags := make([]map[string][]string, numIngesters)
158+
scopeTypes := []string{"resource", "span", "event", "instrumentation"}
159+
160+
for i := 0; i < numIngesters; i++ {
161+
tags := make(map[string][]string)
162+
for j := 0; j < numTagsPerIngester; j++ {
163+
scope := scopeTypes[j%len(scopeTypes)]
164+
value := fmt.Sprintf("tag_%d_%d", i, j)
165+
tags[scope] = append(tags[scope], value)
166+
}
167+
ingesterTags[i] = tags
168+
}
169+
170+
limits := []int{
171+
0, // no limit
172+
100_000, // 100KB
173+
1_000_000, // 1MB
174+
10_000_000, // 10MB
175+
}
176+
177+
b.ResetTimer() // to exclude the setup time for generating tags
178+
for _, lim := range limits {
179+
b.Run("uniques_limit:"+strconv.Itoa(lim), func(b *testing.B) {
180+
for n := 0; n < b.N; n++ {
181+
scopedDistinctStrings := NewScopedDistinctString(lim)
182+
for _, tags := range ingesterTags {
183+
for scope, values := range tags {
184+
for _, v := range values {
185+
scopedDistinctStrings.Collect(scope, v)
186+
if scopedDistinctStrings.Exceeded() {
187+
break // stop early if limit is reached
188+
}
189+
}
190+
}
191+
}
192+
}
193+
})
194+
195+
b.Run("duplicates_limit:"+strconv.Itoa(lim), func(b *testing.B) {
196+
for n := 0; n < b.N; n++ {
197+
scopedDistinctStrings := NewScopedDistinctString(lim)
198+
for i := 0; i < numIngesters; i++ {
199+
for scope := range ingesterTags[i] {
200+
// collect first item to simulate duplicates
201+
scopedDistinctStrings.Collect(scope, ingesterTags[i][scope][0])
202+
if scopedDistinctStrings.Exceeded() {
203+
break // stop early if limit is reached
204+
}
205+
}
206+
}
207+
}
208+
})
209+
}
210+
}

0 commit comments

Comments
 (0)