perf(storage): memoize hashmap prom labels
Prior to this, each hashmap operation that was instrumented involved initialising a map. Now these maps are pre-initialised. ``` ⇒ benchstat old.txt new.txt name old time/op new time/op delta Index_CreateSeriesListIfNotExist/create_series-8 5.00s ± 3% 5.13s ± 2% +2.50% (p=0.033 n=10+7) Index_CreateSeriesListIfNotExist/already_exist_series-8 557ms ± 3% 530ms ± 6% -4.85% (p=0.001 n=10+8) name old alloc/op new alloc/op delta Index_CreateSeriesListIfNotExist/create_series-8 2.57GB ± 0% 1.84GB ± 1% -28.52% (p=0.000 n=8+10) Index_CreateSeriesListIfNotExist/already_exist_series-8 678MB ± 0% 308MB ± 0% -54.55% (p=0.000 n=10+8) name old allocs/op new allocs/op delta Index_CreateSeriesListIfNotExist/create_series-8 28.9M ± 0% 24.5M ± 0% -15.22% (p=0.000 n=9+10) Index_CreateSeriesListIfNotExist/already_exist_series-8 2.23M ± 0% 0.03M ± 0% -98.51% (p=0.000 n=10+10) ```pull/14638/head
parent
9f3cbdc80e
commit
94dbbdca7b
|
@ -278,23 +278,41 @@ func (m *HashMap) PrometheusCollectors() []prometheus.Collector {
|
|||
}
|
||||
|
||||
type rhhTracker struct {
|
||||
metrics *Metrics
|
||||
labels prometheus.Labels
|
||||
enabled bool
|
||||
metrics *Metrics
|
||||
enabled bool
|
||||
baseLabels prometheus.Labels
|
||||
|
||||
// Prevent allocations by initialising these static maps when creating a
|
||||
// new tracker.
|
||||
hitIncLabels prometheus.Labels
|
||||
missIncLabels prometheus.Labels
|
||||
}
|
||||
|
||||
// Labels returns a copy of the default labels used by the tracker's metrics.
|
||||
// The returned map is safe for modification.
|
||||
func (t *rhhTracker) Labels() prometheus.Labels {
|
||||
labels := make(prometheus.Labels, len(t.labels))
|
||||
for k, v := range t.labels {
|
||||
labels := make(prometheus.Labels, len(t.baseLabels))
|
||||
for k, v := range t.baseLabels {
|
||||
labels[k] = v
|
||||
}
|
||||
return labels
|
||||
}
|
||||
|
||||
func newRHHTracker(metrics *Metrics, defaultLabels prometheus.Labels) *rhhTracker {
|
||||
return &rhhTracker{metrics: metrics, labels: defaultLabels, enabled: true}
|
||||
tracker := &rhhTracker{metrics: metrics, enabled: true}
|
||||
|
||||
// Create a copy of the provided labels.
|
||||
tracker.baseLabels = make(prometheus.Labels, len(defaultLabels))
|
||||
for k, v := range defaultLabels {
|
||||
tracker.baseLabels[k] = v
|
||||
}
|
||||
|
||||
tracker.hitIncLabels = tracker.Labels()
|
||||
tracker.hitIncLabels["status"] = "hit"
|
||||
tracker.missIncLabels = tracker.Labels()
|
||||
tracker.missIncLabels["status"] = "miss"
|
||||
|
||||
return tracker
|
||||
}
|
||||
|
||||
func (t *rhhTracker) SetLoadFactor(load float64) {
|
||||
|
@ -302,8 +320,7 @@ func (t *rhhTracker) SetLoadFactor(load float64) {
|
|||
return
|
||||
}
|
||||
|
||||
labels := t.Labels()
|
||||
t.metrics.LoadFactor.With(labels).Set(load)
|
||||
t.metrics.LoadFactor.With(t.baseLabels).Set(load)
|
||||
}
|
||||
|
||||
func (t *rhhTracker) SetSize(sz uint64) {
|
||||
|
@ -311,8 +328,7 @@ func (t *rhhTracker) SetSize(sz uint64) {
|
|||
return
|
||||
}
|
||||
|
||||
labels := t.Labels()
|
||||
t.metrics.Size.With(labels).Set(float64(sz))
|
||||
t.metrics.Size.With(t.baseLabels).Set(float64(sz))
|
||||
}
|
||||
|
||||
func (t *rhhTracker) ObserveGet(d time.Duration) {
|
||||
|
@ -320,9 +336,8 @@ func (t *rhhTracker) ObserveGet(d time.Duration) {
|
|||
return
|
||||
}
|
||||
|
||||
labels := t.Labels()
|
||||
t.metrics.GetDuration.With(labels).Observe(float64(d.Nanoseconds()))
|
||||
t.metrics.LastGetDuration.With(labels).Set(float64(d.Nanoseconds()))
|
||||
t.metrics.GetDuration.With(t.baseLabels).Observe(float64(d.Nanoseconds()))
|
||||
t.metrics.LastGetDuration.With(t.baseLabels).Set(float64(d.Nanoseconds()))
|
||||
}
|
||||
|
||||
func (t *rhhTracker) ObservePut(d time.Duration) {
|
||||
|
@ -330,9 +345,8 @@ func (t *rhhTracker) ObservePut(d time.Duration) {
|
|||
return
|
||||
}
|
||||
|
||||
labels := t.Labels()
|
||||
t.metrics.InsertDuration.With(labels).Observe(float64(d.Nanoseconds()))
|
||||
t.metrics.LastInsertDuration.With(labels).Set(float64(d.Nanoseconds()))
|
||||
t.metrics.InsertDuration.With(t.baseLabels).Observe(float64(d.Nanoseconds()))
|
||||
t.metrics.LastInsertDuration.With(t.baseLabels).Set(float64(d.Nanoseconds()))
|
||||
}
|
||||
|
||||
func (t *rhhTracker) SetGrowDuration(d time.Duration) {
|
||||
|
@ -340,8 +354,7 @@ func (t *rhhTracker) SetGrowDuration(d time.Duration) {
|
|||
return
|
||||
}
|
||||
|
||||
labels := t.Labels()
|
||||
t.metrics.LastGrowDuration.With(labels).Set(d.Seconds())
|
||||
t.metrics.LastGrowDuration.With(t.baseLabels).Set(d.Seconds())
|
||||
}
|
||||
|
||||
// TODO(edd): currently no safe way to calculate this concurrently.
|
||||
|
@ -350,8 +363,7 @@ func (t *rhhTracker) SetProbeCount(length float64) {
|
|||
return
|
||||
}
|
||||
|
||||
labels := t.Labels()
|
||||
t.metrics.MeanProbeCount.With(labels).Set(length)
|
||||
t.metrics.MeanProbeCount.With(t.baseLabels).Set(length)
|
||||
}
|
||||
|
||||
func (t *rhhTracker) incGet(status string) {
|
||||
|
@ -359,8 +371,10 @@ func (t *rhhTracker) incGet(status string) {
|
|||
return
|
||||
}
|
||||
|
||||
labels := t.Labels()
|
||||
labels["status"] = status
|
||||
labels := t.hitIncLabels
|
||||
if status == "miss" {
|
||||
labels = t.missIncLabels
|
||||
}
|
||||
t.metrics.Gets.With(labels).Inc()
|
||||
}
|
||||
|
||||
|
@ -372,8 +386,10 @@ func (t *rhhTracker) incPut(status string) {
|
|||
return
|
||||
}
|
||||
|
||||
labels := t.Labels()
|
||||
labels["status"] = status
|
||||
labels := t.hitIncLabels
|
||||
if status == "miss" {
|
||||
labels = t.missIncLabels
|
||||
}
|
||||
t.metrics.Puts.With(labels).Inc()
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue