Skip to content

improve performance of registry.metrics()#373

Closed
doochik wants to merge 5 commits into
prometheus:masterfrom
doochik:improve-metrics-performance
Closed

improve performance of registry.metrics()#373
doochik wants to merge 5 commits into
prometheus:masterfrom
doochik:improve-metrics-performance

Conversation

@doochik

@doochik doochik commented May 14, 2020

Copy link
Copy Markdown
Contributor

I've rebased original PR #276 and achieve the same results

### Summary:

✓ registry ➭ getMetricsAsJSON#1 with 64 is 1.900% faster.
✓ registry ➭ getMetricsAsJSON#2 with 8 is 2.054% faster.
⚠ registry ➭ getMetricsAsJSON#2 with 4 and 2 with 2 is 7.658% acceptably slower.
✓ registry ➭ getMetricsAsJSON#2 with 2 and 2 with 4 is 8.235% faster.
✓ registry ➭ getMetricsAsJSON#6 with 2 is 4.261% faster.
✓ registry ➭ metrics#1 with 64 is 6.524% faster.
✓ registry ➭ metrics#2 with 8 is 35.91% faster.
✓ registry ➭ metrics#2 with 4 and 2 with 2 is 26.44% faster.
✓ registry ➭ metrics#2 with 2 and 2 with 4 is 31.02% faster.
✓ registry ➭ metrics#6 with 2 is 34.78% faster.
✓ histogram ➭ observe#1 with 64 is 10.78% faster.
✓ histogram ➭ observe#2 with 8 is 9.954% faster.
✓ histogram ➭ observe#2 with 4 and 2 with 2 is 18.51% faster.
✓ histogram ➭ observe#2 with 2 and 2 with 4 is 5.529% faster.
✓ histogram ➭ observe#6 with 2 is 4.469% faster.
⚠ summary ➭ observe#1 with 64 is 0.7088% acceptably slower.
✓ summary ➭ observe#2 with 8 is 0.8064% faster.
⚠ summary ➭ observe#2 with 4 and 2 with 2 is 0.8744% acceptably slower.
⚠ summary ➭ observe#2 with 2 and 2 with 4 is 3.878% acceptably slower.
✓ summary ➭ observe#6 with 2 is 2.453% faster.

@zbjornson zbjornson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for rebasing and for your patience! Much easier to review now.

My two main concerns are ⭐'ed.

Comment thread package-lock.json Outdated
Comment thread lib/counter.js Outdated
Comment thread test/registerTest.js Outdated
Comment thread test/registerTest.js Outdated
Comment thread lib/formatter.js Outdated
Comment thread lib/formatter.js
const name = metric.name;
const help = escapeString(metric.help);
const type = metric.type;
const labelsCode = getLabelsCode(metric, defaultLabelNames, defaultLabels);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⭐ This is going to make it impossible to implement #298/landing #368. As you can tell from the comments in those, I'm not certain what the fate of that issue is though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify what do you mean? Should I rewrite it or implement inside generated function?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zbjornson can you take a look on this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the nudge, will review this PR this weekend.

On this particular comment: I'd (strongly) lean toward making the formatter work with dynamically declared labels. #298 has quite a bit of support so I suspect #368 will land. The main (probably minor) thing holding it up is #298 (comment).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This eliminate the main idea of formatter - build labels string once.
I need to think how to rewrite this.

Comment thread lib/formatter.js Outdated
Comment thread lib/formatter.js
function getLabelsCode(metric, defaultLabelNames, defaultLabels) {
let labelString = '';
const labelNames = getLabelNames(metric, defaultLabelNames);
for (let index = 0; index < labelNames.length; index++) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⭐ It's valid to only set values for a subset of labels when a metric is updated. With this test:

it('should allow subsetse of labels', () => {
	instance = new Gauge({
		name: 'name_2',
		help: 'help',
		labelNames: ['code', 'success'],
	});
	instance.inc({ code: '200' }, 10);
	const str = globalRegistry.getSingleMetricAsString('name_2');
	console.log(str);
});

in this PR, you get

# HELP name_2 help
# TYPE name_2 gauge
name_2{code="200",success="undefined"} 10

whereas in master, you get

# HELP name_2 help
# TYPE name_2 gauge
name_2{code="200"} 10

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should add this as a test, no?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, of course. I’ll fix it

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The above test case passes, but now if the first label is undefined, there's a stray leading comma:

it.only('should allow combinations of labels', () => {
	instance = new Gauge({
		name: 'name_2',
		help: 'help',
		labelNames: ['code', 'success', 'ok'],
	});
	instance.inc({ code: '200' }, 10);
	instance.inc({ code: '200', ok: 'yes' }, 10);
	instance.inc({ ok: 'yes', success: 'false' }, 10);
	instance.inc({ success: 'false', ok: 'no' }, 10);
	const str = globalRegistry.getSingleMetricAsString('name_2');
	console.log(str);
});

prints

      # HELP name_2 help
      # TYPE name_2 gauge
      name_2{code="200"} 10
      name_2{code="200",ok="yes"} 10
      name_2{,success="false",ok="yes"} 10
      name_2{,success="false",ok="no"} 10

(notice last two lines)

Something like these should both be committed as test cases. Do you feel like adding them please?


Just checked, benchmarks still look significantly faster despite the new branch added in the last commits. 👍

@doochik doochik force-pushed the improve-metrics-performance branch from 5bf5779 to a1a3675 Compare May 18, 2020 06:21
@SimenB

SimenB commented Aug 24, 2020

Copy link
Copy Markdown
Collaborator

Any news here? 🙂

@SimenB

SimenB commented Jan 16, 2024

Copy link
Copy Markdown
Collaborator

Does this still provide improvements after #594?

@doochik doochik closed this Jan 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants