Skip to content

Commit a88a5c3

Browse files
authored
perf: improve the memory usage of histogram (#606)
1 parent 4d186fd commit a88a5c3

File tree

4 files changed

+56
-16
lines changed

4 files changed

+56
-16
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ node_modules
44
*.log
55
coverage/
66
package-lock.json
7+
*.heapsnapshot

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ project adheres to [Semantic Versioning](http://semver.org/).
1111

1212
### Changed
1313

14+
- Improve the memory usage of histograms when the `enableExemplars` option is disabled
15+
1416
### Added
1517

1618
## [15.1.0] - 2023-12-15

example/histogram-large-memory.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict';
2+
3+
const v8 = require('v8');
4+
const { register, Histogram } = require('..');
5+
6+
// Create more metrics
7+
8+
async function run() {
9+
const labelNames = Array(10).map((_, idx) => `label_${idx}`);
10+
11+
const getRandomLabels = () =>
12+
labelNames.reduce((acc, label) => {
13+
return { ...acc, [label]: `value_${Math.random()}` };
14+
}, {});
15+
16+
for (let i = 0; i < 100000; i++) {
17+
const h = new Histogram({
18+
name: `test_histogram_${i}`,
19+
help: `Example of a histogram ${i}`,
20+
buckets: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],
21+
labelNames,
22+
});
23+
h.observe(getRandomLabels(), Math.random());
24+
}
25+
26+
await register.metrics();
27+
28+
global.gc();
29+
30+
v8.writeHeapSnapshot();
31+
}
32+
33+
run();

lib/histogram.js

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,6 @@ class Histogram extends Metric {
2626
this.defaultExemplarLabelSet = {};
2727
this.enableExemplars = false;
2828

29-
if (config.enableExemplars) {
30-
this.enableExemplars = true;
31-
this.observe = this.observeWithExemplar;
32-
} else {
33-
this.observe = this.observeWithoutExemplar;
34-
}
35-
3629
for (const label of this.labelNames) {
3730
if (label === 'le') {
3831
throw new Error('le is a reserved label keyword');
@@ -45,13 +38,19 @@ class Histogram extends Metric {
4538
return acc;
4639
}, {});
4740

48-
this.bucketExemplars = this.upperBounds.reduce((acc, upperBound) => {
49-
acc[upperBound] = null;
50-
return acc;
51-
}, {});
41+
if (config.enableExemplars) {
42+
this.enableExemplars = true;
43+
this.bucketExemplars = this.upperBounds.reduce((acc, upperBound) => {
44+
acc[upperBound] = null;
45+
return acc;
46+
}, {});
47+
Object.freeze(this.bucketExemplars);
48+
this.observe = this.observeWithExemplar;
49+
} else {
50+
this.observe = this.observeWithoutExemplar;
51+
}
5252

5353
Object.freeze(this.bucketValues);
54-
Object.freeze(this.bucketExemplars);
5554
Object.freeze(this.upperBounds);
5655

5756
if (this.labelNames.length === 0) {
@@ -263,13 +262,16 @@ function observe(labels) {
263262
}
264263

265264
function createBaseValues(labels, bucketValues, bucketExemplars) {
266-
return {
265+
const result = {
267266
labels,
268267
bucketValues: { ...bucketValues },
269-
bucketExemplars: { ...bucketExemplars },
270268
sum: 0,
271269
count: 0,
272270
};
271+
if (bucketExemplars) {
272+
result.bucketExemplars = { ...bucketExemplars };
273+
}
274+
return result;
273275
}
274276

275277
function convertLabelsAndValues(labels, value) {
@@ -294,7 +296,9 @@ function extractBucketValuesForExport(histogram) {
294296
{ le: upperBound },
295297
acc,
296298
name,
297-
bucketData.bucketExemplars[upperBound],
299+
bucketData.bucketExemplars
300+
? bucketData.bucketExemplars[upperBound]
301+
: null,
298302
bucketData.labels,
299303
);
300304
});
@@ -312,7 +316,7 @@ function addSumAndCountForExport(histogram) {
312316
infLabel,
313317
d.data.count,
314318
`${histogram.name}_bucket`,
315-
d.data.bucketExemplars['-1'],
319+
d.data.bucketExemplars ? d.data.bucketExemplars['-1'] : null,
316320
d.data.labels,
317321
),
318322
setValuePair(

0 commit comments

Comments
 (0)