Skip to content

Commit abaeafe

Browse files
committed
Added fast path to normal (empty) registry to save 8 allocs and 3K5B per Gather.
Signed-off-by: Bartlomiej Plotka <[email protected]>
1 parent 3dcf61c commit abaeafe

File tree

2 files changed

+20
-13
lines changed

2 files changed

+20
-13
lines changed

prometheus/cache.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,6 @@ type CollectSession struct {
7272
currentByName map[string]*dto.MetricFamily
7373
}
7474

75-
func (s *CollectSession) Commit() {
76-
// TODO(bwplotka): Sort metrics within family.
77-
s.c.metricFamilyByName = s.currentByName
78-
s.c.metrics = s.currentMetrics
79-
80-
s.closed = true
81-
s.c.pendingSession = false
82-
}
83-
8475
func (s *CollectSession) MustAddMetric(fqName, help string, labelNames, labelValues []string, valueType ValueType, value float64, ts *time.Time) {
8576
if err := s.AddMetric(fqName, help, labelNames, labelValues, valueType, value, ts); err != nil {
8677
panic(err)
@@ -95,7 +86,7 @@ func (s *CollectSession) AddMetric(fqName, help string, labelNames, labelValues
9586
}
9687

9788
// Label names can be unsorted, will be sorting them later. The only implication is cachability if
98-
// consumer provide non-deterministic order of those (unlikely since label values has to be matched.
89+
// consumer provide non-deterministic order of those (unlikely since label values has to be matched).
9990

10091
if len(labelNames) != len(labelValues) {
10192
return errors.New("new metric: label name has different len than values")
@@ -125,7 +116,7 @@ func (s *CollectSession) AddMetric(fqName, help string, labelNames, labelValues
125116
h := xxhash.New()
126117
h.WriteString(fqName)
127118
h.Write(separatorByteSlice)
128-
for i := range labelNames {
119+
for i := range labelNames { // Ofc not in the same order...
129120
h.WriteString(labelNames[i])
130121
h.Write(separatorByteSlice)
131122
h.WriteString(labelValues[i])
@@ -149,7 +140,6 @@ func (s *CollectSession) AddMetric(fqName, help string, labelNames, labelValues
149140
}
150141
sort.Sort(labelPairSorter(m.Label))
151142
}
152-
s.currentMetrics[hSum] = m
153143
switch valueType {
154144
case CounterValue:
155145
v := m.Counter
@@ -186,12 +176,22 @@ func (s *CollectSession) AddMetric(fqName, help string, labelNames, labelValues
186176
if ts != nil {
187177
m.TimestampMs = proto.Int64(ts.Unix()*1000 + int64(ts.Nanosecond()/1000000))
188178
}
179+
s.currentMetrics[hSum] = m
189180

190181
// Will be sorted later.
191182
d.Metric = append(d.Metric, m)
192183
return nil
193184
}
194185

186+
func (s *CollectSession) Commit() {
187+
// TODO(bwplotka): Sort metrics within family.
188+
s.c.metricFamilyByName = s.currentByName
189+
s.c.metrics = s.currentMetrics
190+
191+
s.closed = true
192+
s.c.pendingSession = false
193+
}
194+
195195
type BlockingRegistry struct {
196196
*Registry
197197

prometheus/registry.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,14 @@ func (r *Registry) MustRegister(cs ...Collector) {
407407

408408
// Gather implements Gatherer.
409409
func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
410+
r.mtx.RLock()
411+
412+
if len(r.collectorsByID) == 0 && len(r.uncheckedCollectors) == 0 {
413+
// Fast path.
414+
r.mtx.RUnlock()
415+
return nil, nil
416+
}
417+
410418
var (
411419
checkedMetricChan = make(chan Metric, capMetricChan)
412420
uncheckedMetricChan = make(chan Metric, capMetricChan)
@@ -416,7 +424,6 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
416424
registeredDescIDs map[uint64]struct{} // Only used for pedantic checks
417425
)
418426

419-
r.mtx.RLock()
420427
goroutineBudget := len(r.collectorsByID) + len(r.uncheckedCollectors)
421428
metricFamiliesByName := make(map[string]*dto.MetricFamily, len(r.dimHashesByName))
422429
checkedCollectors := make(chan Collector, len(r.collectorsByID))

0 commit comments

Comments
 (0)