Skip to content

Commit

Permalink
Merge pull request #297 from DataDog/corentin.chary/performance-impro…
Browse files Browse the repository at this point in the history
…vements

aggregator: don't allocate memory if we don't have tags
  • Loading branch information
iksaif committed Dec 20, 2023
2 parents 112920c + 2e8198d commit 515814d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 5 deletions.
10 changes: 9 additions & 1 deletion statsd/aggregator.go
Expand Up @@ -172,14 +172,22 @@ func (a *aggregator) flushMetrics() []metric {
return metrics
}

// getContext returns the context for a metric name and tags.
//
// The context is the metric name and tags separated by a separator symbol.
// It is not intended to be used as a metric name but as a unique key to aggregate
func getContext(name string, tags []string) string {
c, _ := getContextAndTags(name, tags)
return c
}

// getContextAndTags returns the context and tags for a metric name and tags.
//
// See getContext for usage for context
// The tags are the tags separated by a separator symbol and can be re-used to pass down to the writer
func getContextAndTags(name string, tags []string) (string, string) {
if len(tags) == 0 {
return name + nameSeparatorSymbol, ""
return name, ""
}
n := len(name) + len(nameSeparatorSymbol) + len(tagSeparatorSymbol)*(len(tags)-1)
for _, s := range tags {
Expand Down
20 changes: 19 additions & 1 deletion statsd/aggregator_test.go
Expand Up @@ -377,7 +377,7 @@ func TestGetContextAndTags(t *testing.T) {
testName: "no tags",
name: "name",
tags: nil,
wantContext: "name:",
wantContext: "name",
wantTags: "",
},
{
Expand All @@ -403,3 +403,21 @@ func TestGetContextAndTags(t *testing.T) {
})
}
}

func BenchmarkGetContext(b *testing.B) {
name := "test.metric"
tags := []string{"tag:tag", "foo:bar"}
for i := 0; i < b.N; i++ {
getContext(name, tags)
}
b.ReportAllocs()
}

func BenchmarkGetContextNoTags(b *testing.B) {
name := "test.metric"
var tags []string
for i := 0; i < b.N; i++ {
getContext(name, tags)
}
b.ReportAllocs()
}
16 changes: 13 additions & 3 deletions statsd/statsd_benchmark_test.go
Expand Up @@ -26,7 +26,15 @@ func setupUDSClientServer(b *testing.B, options []statsd.Option) (*statsd.Client
}
go func() {
for {
_, err := conn.Accept()
c, err := conn.Accept()
// We need to read everything from the socket to avoid blocking the sender
buf := make([]byte, 1024)
for {
_, err = c.Read(buf)
if err != nil {
break
}
}
if err != nil {
return
}
Expand Down Expand Up @@ -76,8 +84,9 @@ func benchmarkStatsdDifferentMetrics(b *testing.B, transport string, extraOption
b.RunParallel(func(pb *testing.PB) {
testNumber := atomic.AddInt32(&n, 1)
name := fmt.Sprintf("test.metric%d", testNumber)
tags := []string{"tag:tag"}
for pb.Next() {
client.Gauge(name, 1, []string{"tag:tag"}, 1)
client.Gauge(name, 1, tags, 1)
}
})
client.Flush()
Expand All @@ -96,7 +105,8 @@ func benchmarkStatsdSameMetrics(b *testing.B, transport string, extraOptions ...

b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
client.Gauge("test.metric", 1, []string{"tag:tag"}, 1)
tags := []string{"tag:tag"}
client.Gauge("test.metric", 1, tags, 1)
}
})
client.Flush()
Expand Down

0 comments on commit 515814d

Please sign in to comment.