Skip to content

Commit

Permalink
Improve performance of WithLabelValues(...)
Browse files Browse the repository at this point in the history
The slice with variadic arguments passed to MetricVec.WithLabelValues()
was escaping to heap. This change fixes that by performing a copy of the
slice before passing it to fmt.Errorf(), which is where the slice was
escaping. This keeps the hot path without that allocation.

Meaningful benchmark results (skipping ~0 CPU and 0 alloc ones):

                                                               │    old.txt    │               new.txt                │
                                                               │    sec/op     │    sec/op     vs base                │
Counter/With_Label_Values-16                                     108.00n ±  6%   58.06n ±  1%  -46.24% (p=0.000 n=10)
Counter/With_Label_Values_and_Constraint-16                       174.5n ± 15%   136.8n ±  6%  -21.63% (p=0.000 n=10)
Counter/With_triple_Label_Values-16                               309.3n ± 12%   172.9n ±  1%  -44.08% (p=0.000 n=10)
Counter/With_triple_Label_Values_and_Constraint-16                591.5n ± 11%   418.9n ±  3%  -29.17% (p=0.000 n=10)
Counter/With_repeated_Label_Values-16                             212.9n ± 10%   116.8n ± 23%  -45.16% (p=0.000 n=10)
Counter/With_repeated_Label_Values_and_Constraint-16              406.2n ± 14%   275.1n ±  4%  -32.30% (p=0.000 n=10)
CounterWithLabelValuesConcurrent-16                               85.45n ±  2%   89.09n ±  2%   +4.26% (p=0.003 n=10)

                                                               │    old.txt     │                  new.txt                  │
                                                               │      B/op      │     B/op      vs base                     │
Counter/With_Label_Values-16                                       48.00 ± 0%        0.00 ± 0%  -100.00% (p=0.000 n=10)
Counter/With_Label_Values_and_Constraint-16                        96.00 ± 0%       48.00 ± 0%   -50.00% (p=0.000 n=10)
Counter/With_triple_Label_Values-16                                144.0 ± 0%         0.0 ± 0%  -100.00% (p=0.000 n=10)
Counter/With_triple_Label_Values_and_Constraint-16                 288.0 ± 0%       144.0 ± 0%   -50.00% (p=0.000 n=10)
Counter/With_repeated_Label_Values-16                              96.00 ± 0%        0.00 ± 0%  -100.00% (p=0.000 n=10)
Counter/With_repeated_Label_Values_and_Constraint-16              192.00 ± 0%       96.00 ± 0%   -50.00% (p=0.000 n=10)
CounterWithLabelValuesConcurrent-16                                48.00 ± 0%        0.00 ± 0%  -100.00% (p=0.000 n=10)

                                                               │   old.txt    │                 new.txt                 │
                                                               │  allocs/op   │ allocs/op   vs base                     │
Counter/With_Label_Values-16                                     1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=10)
Counter/With_Label_Values_and_Constraint-16                      2.000 ± 0%     1.000 ± 0%   -50.00% (p=0.000 n=10)
Counter/With_triple_Label_Values-16                              3.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=10)
Counter/With_triple_Label_Values_and_Constraint-16               6.000 ± 0%     3.000 ± 0%   -50.00% (p=0.000 n=10)
Counter/With_repeated_Label_Values-16                            2.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=10)
Counter/With_repeated_Label_Values_and_Constraint-16             4.000 ± 0%     2.000 ± 0%   -50.00% (p=0.000 n=10)
CounterWithLabelValuesConcurrent-16                              1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=10)

Signed-off-by: Oleg Zaytsev <[email protected]>
  • Loading branch information
colega committed Oct 4, 2023
1 parent 4c10365 commit 005d8de
Showing 1 changed file with 2 additions and 0 deletions.
2 changes: 2 additions & 0 deletions prometheus/labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ func validateValuesInLabels(labels Labels, expectedNumberOfValues int) error {

func validateLabelValues(vals []string, expectedNumberOfValues int) error {
if len(vals) != expectedNumberOfValues {
// The call below makes vals escape, copy them to avoid that.
vals := append([]string(nil), vals...)
return fmt.Errorf(
"%w: expected %d label values but got %d in %#v",
errInconsistentCardinality, expectedNumberOfValues,
Expand Down

0 comments on commit 005d8de

Please sign in to comment.