Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Experiment] fastdto for MakePairLabels (on top of #1734) #1746

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft

Conversation

bwplotka
Copy link
Member

Experimenting with tailored dto for #1734

*dto.LabelPairs are pretty bad. We got stuck with *dto.Metric in our API since the beginning. This is problematic with the notorious use of small objects and pointers everywhere and all structs are bigger to support unknown fields and parsing. We don't need any of this in client_golang - it's just overhead for us. We only need interim struct and fast encoding.

This is also the reason why we can't optimize #1734 further.

We always wanted to do move out, but we can't change dto.Metric use due to compatibility....

...unless we can (:

We could start introducing it slowly and then do Write2(m fastdto.Metric) or so API if we want (or release v2 client golang which I would love to avoid).

Benchmarks are not ideal. I think it keeps the CPU adventage of #1734, but "reverts" the allocs to where they were.

benchstat newDesc-v1.txt newDesc-v2.txt 
goos: darwin
goarch: arm64
pkg: github.com/prometheus/client_golang/prometheus
                    │ newDesc-v1.txt │           newDesc-v2.txt            │
                    │     sec/op     │    sec/op     vs base               │
NewDesc/labels=1-2      547.5n ± 15%   420.8n ±  6%  -23.14% (p=0.002 n=6)
NewDesc/labels=3-2     1152.5n ±  3%   879.6n ± 17%  -23.68% (p=0.002 n=6)
NewDesc/labels=10-2     4.955µ ±  3%   3.929µ ±  6%  -20.71% (p=0.002 n=6)
geomean                 1.462µ         1.133µ        -22.52%

                    │ newDesc-v1.txt │           newDesc-v2.txt            │
                    │      B/op      │     B/op      vs base               │
NewDesc/labels=1-2        504.0 ± 0%     376.0 ± 0%  -25.40% (p=0.002 n=6)
NewDesc/labels=3-2       1064.0 ± 0%     680.0 ± 0%  -36.09% (p=0.002 n=6)
NewDesc/labels=10-2     4.488Ki ± 0%   3.301Ki ± 0%  -26.46% (p=0.002 n=6)
geomean                 1.319Ki          952.5       -29.48%

                    │ newDesc-v1.txt │          newDesc-v2.txt           │
                    │   allocs/op    │ allocs/op   vs base               │
NewDesc/labels=1-2        15.00 ± 0%   10.00 ± 0%  -33.33% (p=0.002 n=6)
NewDesc/labels=3-2        27.00 ± 0%   12.00 ± 0%  -55.56% (p=0.002 n=6)
NewDesc/labels=10-2       72.00 ± 0%   22.00 ± 0%  -69.44% (p=0.002 n=6)
geomean                   30.78        13.82       -55.10%
benchstat makeLabelPairs-v1.txt makeLabelPairs-v2.txt
goos: darwin
goarch: arm64
pkg: github.com/prometheus/client_golang/prometheus
                           │ makeLabelPairs-v1.txt │       makeLabelPairs-v2.txt        │
                           │        sec/op         │    sec/op     vs base              │
MakeLabelPairs/labels=1-2             65.21n ±  6%   66.42n ± 19%       ~ (p=0.132 n=6)
MakeLabelPairs/labels=3-2             156.8n ±  1%   171.2n ±  3%  +9.18% (p=0.002 n=6)
MakeLabelPairs/labels=10-2            501.5n ± 12%   516.2n ±  4%       ~ (p=0.310 n=6)
geomean                               172.4n         180.4n        +4.61%

                           │ makeLabelPairs-v1.txt │       makeLabelPairs-v2.txt        │
                           │         B/op          │    B/op      vs base               │
MakeLabelPairs/labels=1-2               96.00 ± 0%   144.00 ± 0%  +50.00% (p=0.002 n=6)
MakeLabelPairs/labels=3-2               288.0 ± 0%    432.0 ± 0%  +50.00% (p=0.002 n=6)
MakeLabelPairs/labels=10-2              960.0 ± 0%   1440.0 ± 0%  +50.00% (p=0.002 n=6)
geomean                                 298.3         447.4       +50.00%

                           │ makeLabelPairs-v1.txt │       makeLabelPairs-v2.txt        │
                           │       allocs/op       │ allocs/op   vs base                │
MakeLabelPairs/labels=1-2               3.000 ± 0%   3.000 ± 0%       ~ (p=1.000 n=6) ¹
MakeLabelPairs/labels=3-2               7.000 ± 0%   7.000 ± 0%       ~ (p=1.000 n=6) ¹
MakeLabelPairs/labels=10-2              21.00 ± 0%   21.00 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                 7.612        7.612       +0.00%
¹ all samples are equal

I think for the next iteration we could try moving this cost to Write (so when collect is used). When collecting one could pool/reuse dto.Metrics OR use Write2 with fastdto Metric 🤔

Signed-off-by: bwplotka <[email protected]>
@@ -215,25 +214,22 @@ func populateMetric(
// This function is only needed for custom Metric implementations. See MetricVec
// example.
func MakeLabelPairs(desc *Desc, labelValues []string) []*dto.LabelPair {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's an opportunity to move this to []fastdto.LabelPair and pay the price of allocs on Write 🤔 (on scrape)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants