diff --git a/CHANGELOG.md b/CHANGELOG.md index 61b4bf66..a4a2f6e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ project adheres to [Semantic Versioning](http://semver.org/). ### Changed - Organized default metrics +- perf: Histogram rendering builds its export list straight from the store iterator instead of an intermediate array. Faster at high series counts on Node 24 and 26, can be slightly slower on Node 22 ### Added diff --git a/benchmarks/histogram.js b/benchmarks/histogram.js index 9e51dcfa..0a940632 100644 --- a/benchmarks/histogram.js +++ b/benchmarks/histogram.js @@ -14,7 +14,11 @@ 'use strict'; -const { getLabelNames, labelCombinationFactory } = require('./utils/labels'); +const { + getLabelNames, + getLabelCombinations, + labelCombinationFactory, +} = require('./utils/labels'); module.exports = setupHistogramSuite; @@ -100,6 +104,19 @@ function setupHistogramSuite(suite) { ), { teardown, setup: setup(6) }, ); + + // `method` repeats `delete`, so `1 x 64` stores 63 label sets and `2 x 8` stores 56. + [ + { name: 'no labels', counts: [] }, + { name: '1 x 64', counts: [64] }, + { name: '2 x 8', counts: [8, 8] }, + { name: '6 x 2', counts: [2, 2, 2, 2, 2, 2] }, + ].forEach(({ name, counts }) => { + suite.add(`get() ${name}`, (client, { histogram }) => histogram.get(), { + teardown, + setup: observed(counts), + }); + }); } function setup(labelCount) { @@ -117,6 +134,25 @@ function setup(labelCount) { }; } +function observed(labelCounts) { + return client => { + const registry = new client.Registry(); + + const histogram = new client.Histogram({ + name: 'histogram', + help: 'histogram', + labelNames: getLabelNames(labelCounts.length), + registers: [registry], + }); + + getLabelCombinations(labelCounts).forEach(labels => + histogram.observe({ ...labels }, 1), + ); + + return { registry, histogram }; + }; +} + function teardown(client, { registry }) { registry.clear(); } diff --git a/lib/histogram.js b/lib/histogram.js index c87852c3..3265b2e5 100644 --- a/lib/histogram.js +++ b/lib/histogram.js @@ -120,8 +120,8 @@ class Histogram extends Metric { const v = this.collect(); if (v instanceof Promise) await v; } - const data = Array.from(this.store.values()); - const values = data + const values = this.store + .values() .map(extractBucketValuesForExport(this)) .reduce(addSumAndCountForExport(this), []);