mirror of
https://github.com/grafana/grafana.git
synced 2025-01-24 15:27:01 -06:00
Alerting: Improve performance of tupleLablesToLabels function (#88736)
* Alerting: Improve performance of tupleLablesToLabels function Signed-off-by: Dave Henderson <dave.henderson@grafana.com> * use %s for string rather than %v Co-authored-by: Sofia Papagiannaki <1632407+papagian@users.noreply.github.com> --------- Signed-off-by: Dave Henderson <dave.henderson@grafana.com> Co-authored-by: Sofia Papagiannaki <1632407+papagian@users.noreply.github.com>
This commit is contained in:
parent
3a6034b58e
commit
df784917e4
@ -100,12 +100,16 @@ func tupleLablesToLabels(tuples tupleLabels) (InstanceLabels, error) {
|
||||
if tuples == nil {
|
||||
return InstanceLabels{}, nil
|
||||
}
|
||||
labels := make(map[string]string)
|
||||
|
||||
labels := make(map[string]string, len(tuples))
|
||||
for _, tuple := range tuples {
|
||||
if key, ok := labels[tuple[0]]; ok {
|
||||
return nil, fmt.Errorf("duplicate key '%v' in lables: %v", key, tuples)
|
||||
key, value := tuple[0], tuple[1]
|
||||
if _, ok := labels[key]; ok {
|
||||
return nil, fmt.Errorf("duplicate key '%s' in labels: %v", key, tuples)
|
||||
}
|
||||
labels[tuple[0]] = tuple[1]
|
||||
|
||||
labels[key] = value
|
||||
}
|
||||
|
||||
return labels, nil
|
||||
}
|
||||
|
114
pkg/services/ngalert/models/instance_labels_test.go
Normal file
114
pkg/services/ngalert/models/instance_labels_test.go
Normal file
@ -0,0 +1,114 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestTupleLabelsToLabels(t *testing.T) {
|
||||
t.Run("converts tupleLabels to InstanceLabels", func(t *testing.T) {
|
||||
in := tupleLabels{
|
||||
{"foo", "bar"},
|
||||
{"baz", "qux"},
|
||||
}
|
||||
|
||||
labels, err := tupleLablesToLabels(in)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, InstanceLabels{
|
||||
"foo": "bar",
|
||||
"baz": "qux",
|
||||
}, labels)
|
||||
})
|
||||
|
||||
t.Run("nil input gives empty output", func(t *testing.T) {
|
||||
labels, err := tupleLablesToLabels(nil)
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, labels)
|
||||
})
|
||||
|
||||
t.Run("duplicate keys are not allowed", func(t *testing.T) {
|
||||
in := tupleLabels{
|
||||
{"foo", "bar"},
|
||||
{"foo", "qux"},
|
||||
}
|
||||
|
||||
_, err := tupleLablesToLabels(in)
|
||||
require.Error(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkTupleLabelsToLabels(b *testing.B) {
|
||||
b.Run("10 labels", func(b *testing.B) {
|
||||
in := make(tupleLabels, 0, 10)
|
||||
for i := 0; i < 10; i++ {
|
||||
key := fmt.Sprintf("key%d", i)
|
||||
value := fmt.Sprintf("value%d", i)
|
||||
in = append(in, tupleLabel{key, value})
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := tupleLablesToLabels(in)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("100 labels", func(b *testing.B) {
|
||||
in := make(tupleLabels, 0, 100)
|
||||
for i := 0; i < 100; i++ {
|
||||
key := fmt.Sprintf("key%d", i)
|
||||
value := fmt.Sprintf("value%d", i)
|
||||
in = append(in, tupleLabel{key, value})
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := tupleLablesToLabels(in)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("10_000 labels", func(b *testing.B) {
|
||||
in := make(tupleLabels, 0, 10_000)
|
||||
for i := 0; i < 10_000; i++ {
|
||||
key := fmt.Sprintf("key%d", i)
|
||||
value := fmt.Sprintf("value%d", i)
|
||||
in = append(in, tupleLabel{key, value})
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := tupleLablesToLabels(in)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("1_000_000 labels", func(b *testing.B) {
|
||||
in := make(tupleLabels, 0, 1_000_000)
|
||||
for i := 0; i < 1_000_000; i++ {
|
||||
key := fmt.Sprintf("key%d", i)
|
||||
value := fmt.Sprintf("value%d", i)
|
||||
in = append(in, tupleLabel{key, value})
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := tupleLablesToLabels(in)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue
Block a user