mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
lib/promscrape: reduce memory allocations in promLabelsString() function
This should help with reducing memory usage in https://github.com/VictoriaMetrics/VictoriaMetrics/issues/878
This commit is contained in:
parent
c0bd208c77
commit
c046735571
2 changed files with 44 additions and 3 deletions
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"math/bits"
|
"math/bits"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -121,11 +122,24 @@ func (sw *ScrapeWork) LabelsString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func promLabelsString(labels []prompbmarshal.Label) string {
|
func promLabelsString(labels []prompbmarshal.Label) string {
|
||||||
a := make([]string, 0, len(labels))
|
// Calculate the required memory for storing serialized labels.
|
||||||
|
n := 2 // for `{...}`
|
||||||
for _, label := range labels {
|
for _, label := range labels {
|
||||||
a = append(a, fmt.Sprintf("%s=%q", label.Name, label.Value))
|
n += len(label.Name) + len(label.Value)
|
||||||
|
n += 4 // for `="...",`
|
||||||
}
|
}
|
||||||
return "{" + strings.Join(a, ", ") + "}"
|
b := make([]byte, 0, n)
|
||||||
|
b = append(b, '{')
|
||||||
|
for i, label := range labels {
|
||||||
|
b = append(b, label.Name...)
|
||||||
|
b = append(b, '=')
|
||||||
|
b = strconv.AppendQuote(b, label.Value)
|
||||||
|
if i+1 < len(labels) {
|
||||||
|
b = append(b, ',')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b = append(b, '}')
|
||||||
|
return bytesutil.ToUnsafeString(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
type scrapeWork struct {
|
type scrapeWork struct {
|
||||||
|
|
|
@ -11,6 +11,33 @@ import (
|
||||||
parser "github.com/VictoriaMetrics/VictoriaMetrics/lib/protoparser/prometheus"
|
parser "github.com/VictoriaMetrics/VictoriaMetrics/lib/protoparser/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestPromLabelsString(t *testing.T) {
|
||||||
|
f := func(labels []prompbmarshal.Label, resultExpected string) {
|
||||||
|
t.Helper()
|
||||||
|
result := promLabelsString(labels)
|
||||||
|
if result != resultExpected {
|
||||||
|
t.Fatalf("unexpected result; got\n%s\nwant\n%s", result, resultExpected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f([]prompbmarshal.Label{}, "{}")
|
||||||
|
f([]prompbmarshal.Label{
|
||||||
|
{
|
||||||
|
Name: "foo",
|
||||||
|
Value: "bar",
|
||||||
|
},
|
||||||
|
}, `{foo="bar"}`)
|
||||||
|
f([]prompbmarshal.Label{
|
||||||
|
{
|
||||||
|
Name: "foo",
|
||||||
|
Value: "bar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "a",
|
||||||
|
Value: `"b"`,
|
||||||
|
},
|
||||||
|
}, `{foo="bar",a="\"b\""}`)
|
||||||
|
}
|
||||||
|
|
||||||
func TestScrapeWorkScrapeInternalFailure(t *testing.T) {
|
func TestScrapeWorkScrapeInternalFailure(t *testing.T) {
|
||||||
dataExpected := `
|
dataExpected := `
|
||||||
up 0 123
|
up 0 123
|
||||||
|
|
Loading…
Reference in a new issue