Skip to content

model: sort label names without boxing them into sort.Interface - #963

Merged
bwplotka merged 1 commit into
prometheus:mainfrom
SoloJacobs:main
Aug 24, 2026
Merged

model: sort label names without boxing them into sort.Interface#963
bwplotka merged 1 commit into
prometheus:mainfrom
SoloJacobs:main

Conversation

@SoloJacobs

Copy link
Copy Markdown
Contributor

SignatureForLabels becomes allocation-free, which matters because it is the only exported way to hash a subset of a label set. Alertmanager hit this in its inhibitor: it calls the equivalent once per inhibition rule per alert on GET /api/v2/alerts.

    benchstat over 8 runs (n=8, p=0.000 throughout):
    
      benchmark                     sec/op              B/op        allocs/op
      SignatureForLabels/1     60.71n -> 17.68n      24 -> 0       1 -> 0
      SignatureForLabels/2     95.40n -> 40.34n      24 -> 0       1 -> 0
      SignatureForLabels/3     121.40n -> 70.86n     24 -> 0       1 -> 0
      SignatureWithoutLabels   214.2n -> 184.8n      72 -> 48      2 -> 1

Benchmark here:

func BenchmarkSignatureForLabels(b *testing.B) {
	m := Metric{
		"first-label":  "first-label-value",
		"second-label": "second-label-value",
		"third-label":  "third-label-value",
	}

	for _, n := range []int{1, 2, 3} {
		labels := make([]LabelName, 0, n)
		for ln := range m {
			labels = append(labels, ln)
			if len(labels) == n {
				break
			}
		}
		slices.Sort(labels)

		b.Run(strconv.Itoa(n)+"-labels", func(b *testing.B) {
			b.ReportAllocs()
			for b.Loop() {
				SignatureForLabels(m, labels...)
			}
		})
	}
}

func BenchmarkSignatureWithoutLabels(b *testing.B) {
	m := Metric{
		"first-label":  "first-label-value",
		"second-label": "second-label-value",
		"third-label":  "third-label-value",
	}
	exclude := map[LabelName]struct{}{"first-label": {}}

	b.ReportAllocs()
	for b.Loop() {
		SignatureWithoutLabels(m, exclude)
	}
}

SignatureForLabels becomes allocation-free, which matters because it is
the only exported way to hash a subset of a label set. Alertmanager hit
this in its inhibitor: it calls the equivalent once per inhibition rule
per alert on GET `/api/v2/alerts`.

Signed-off-by: Solomon Jacobs <solomonjacobs@protonmail.com>

@bwplotka bwplotka left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Great, thanks!

@bwplotka
bwplotka merged commit 5042671 into prometheus:main Aug 24, 2026
8 checks passed
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.

5 participants