From dcba71a0b06afc28a3141d66a2a537df1773dd1c Mon Sep 17 00:00:00 2001 From: ismail simsek Date: Wed, 12 Mar 2025 14:12:24 +0100 Subject: [PATCH] Prometheus: Improve native histogram response parsing performance (#102024) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * introduce tests * improve allocation by %61 * ~%27 improvement goos: darwin goarch: arm64 pkg: github.com/grafana/grafana/pkg/promlib/converter cpu: Apple M1 Pro │ pmem.0.txt │ pmem.2.txt │ │ sec/op │ sec/op vs base │ ReadPrometheusStyleResult_FromFile/prom-query-range.json-10 117.72µ ± 6% 82.90µ ± 4% -29.57% (p=0.002 n=6) │ pmem.0.txt │ pmem.2.txt │ │ B/op │ B/op vs base │ ReadPrometheusStyleResult_FromFile/prom-query-range.json-10 104.34Ki ± 0% 76.09Ki ± 0% -27.08% (p=0.002 n=6) │ pmem.0.txt │ pmem.2.txt │ │ allocs/op │ allocs/op vs base │ ReadPrometheusStyleResult_FromFile/prom-query-range.json-10 2463.0 ± 0% 899.0 ± 0% -63.50% (p=0.002 n=6) * add more tests * remove comment lines * read string as slice to prevent type conversion * golang lint * revert appendValueFromString improvement * fix merging issues * improve native histogram response parsing --- pkg/promlib/converter/prom.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/pkg/promlib/converter/prom.go b/pkg/promlib/converter/prom.go index cb7975f978e..504ae33f3ca 100644 --- a/pkg/promlib/converter/prom.go +++ b/pkg/promlib/converter/prom.go @@ -6,6 +6,7 @@ import ( "slices" "strconv" "time" + "unsafe" "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/data" @@ -858,14 +859,17 @@ func readHistogram(iter *sdkjsoniter.Iterator, hist *histogramInfo) error { } func appendValueFromString(iter *sdkjsoniter.Iterator, field *data.Field) error { - var err error - var s string - if s, err = iter.ReadString(); err != nil { + // Read the string directly into our buffer + buf, err := iter.ReadStringAsSlice() + if err != nil { return err } - var v float64 - if v, err = strconv.ParseFloat(s, 64); err != nil { + // #nosec G103 + // Convert string to float64 without allocation + // https://github.com/search?q=org%3Agrafana+yoloString&type=code + v, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&buf)), 64) + if err != nil { return err }