From 26ad852c94e7ce0df78d03767f09b8c8ccafad29 Mon Sep 17 00:00:00 2001 From: Bernerd Schaefer Date: Wed, 11 Sep 2013 17:16:34 +0200 Subject: [PATCH] Cache signature of an empty label set This is an optimization of labelsToSignature to avoid excess allocations when the label set is empty. Change-Id: If2d59bbc3ae6d4457e2ded197b6f4e7c67e6a173 --- prometheus/signature.go | 7 +++++++ prometheus/signature_test.go | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/prometheus/signature.go b/prometheus/signature.go index 075d387..505e51a 100644 --- a/prometheus/signature.go +++ b/prometheus/signature.go @@ -14,9 +14,16 @@ import ( "github.com/prometheus/client_golang/model" ) +// cache the signature of an empty label set. +var emptyLabelSignature = fnv.New64a().Sum64() + // LabelsToSignature provides a way of building a unique signature // (i.e., fingerprint) for a given label set sequence. func labelsToSignature(labels map[string]string) uint64 { + if len(labels) == 0 { + return emptyLabelSignature + } + names := make(model.LabelNames, 0, len(labels)) for name := range labels { names = append(names, model.LabelName(name)) diff --git a/prometheus/signature_test.go b/prometheus/signature_test.go index 81ae66a..9e826ff 100644 --- a/prometheus/signature_test.go +++ b/prometheus/signature_test.go @@ -7,6 +7,7 @@ package prometheus import ( + "runtime" "testing" ) @@ -38,6 +39,25 @@ func TestLabelToSignature(t *testing.T) { testLabelsToSignature(t) } +func TestEmptyLabelSignature(t *testing.T) { + input := []map[string]string{nil, {}} + + var ms runtime.MemStats + runtime.ReadMemStats(&ms) + + alloc := ms.Alloc + + for _, labels := range input { + labelsToSignature(labels) + } + + runtime.ReadMemStats(&ms) + + if got := ms.Alloc; alloc != got { + t.Fatal("expected labelsToSignature with empty labels not to perform allocations") + } +} + func BenchmarkLabelToSignature(b *testing.B) { for i := 0; i < b.N; i++ { testLabelsToSignature(b)