Commit 16d242f
authored
Optimize text format scrape hot path (#202)
* Pre-compute metric name and help as binaries at declaration time
During every scrape, metric name and help were converted from
atom/list to binary via ensure_binary_or_string/1 in create_mf.
With many metric families this repeated work adds up, especially
the atom_to_binary calls that show up in profiling.
Now, extract_common_params/1 returns pre-computed NameBin and
HelpBin, stored in ETS as a 3-tuple {Labels, HelpBin, NameBin}
alongside label definitions. All six built-in metric collectors
(boolean, counter, gauge, histogram, quantile_summary, summary)
pass these binaries directly into create_mf, avoiding per-scrape
conversion entirely.
A normalize_mf_row/1 function in prometheus_metric handles backward
compatibility: old ETS entries with the 2-tuple {Labels, Help}
format are normalized on read, so hot upgrades don't crash.
* prometheus_model_helpers: Optimize hot path for metric record creation
Profiling (tprof) of a RabbitMQ workload shows gauge_metric/2 at
16.32% and counter_metric/2 at 2.45% of total process time, with
~2M calls each allocating 12 words of intermediate records that the
text format immediately destructures and discards.
This commit applies several targeted optimizations:
- Inline gauge_metric/2, counter_metric/2, and label_pair/1 to
eliminate function call overhead on these ~2M-call-per-scrape
functions.
- Add a fast path in create_mf/4 that detects when the input list
already contains #'Metric'{} records (as all built-in collectors
produce), skipping the metrics_from_tuples/2 dispatch entirely.
This avoids the per-element is_record check and type-based
dispatch for every metric.
- Replace lists:map(fun label_pair/1, Labels) with a list
comprehension, which the compiler can optimize better when
combined with the inline directive.
- Add integer and float clauses to ensure_binary_or_string/1,
avoiding the expensive io_lib:format("~p", [Val]) fallback for
numeric label values.
* prometheus_model_helpers: Merge filter and map into single pass
metrics_from_tuples/2 previously traversed the list twice: once
via filter_undefined_metrics (lists:filter) to remove undefined
entries, then a list comprehension to convert tuples to records.
Profiling shows lists:filter alone at 3.26% of scrape time with
~2.4M elements.
Fold both operations into a single list comprehension with a
guard filter. Apply the same pattern to the create_mf/4 fast path
for pre-built #'Metric'{} records.
* prometheus_text_format: Inline render_series/4 and render_value/2
These two functions are called once per metric series during every
scrape (~2.3M calls each in profiled RabbitMQ workloads), together
accounting for ~15.6% of scrape time. Inlining eliminates the
function call overhead and allows the compiler to optimize the
binary append operations across call boundaries.
* Apply review comments1 parent 27ebf45 commit 16d242f
13 files changed
Lines changed: 130 additions & 56 deletions
File tree
- src
- formats
- metrics
- model
- test/eunit
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
38 | | - | |
| 38 | + | |
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
326 | 326 | | |
327 | 327 | | |
328 | 328 | | |
329 | | - | |
330 | | - | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
331 | 333 | | |
332 | 334 | | |
333 | 335 | | |
334 | 336 | | |
335 | 337 | | |
336 | | - | |
| 338 | + | |
337 | 339 | | |
338 | 340 | | |
339 | 341 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
336 | 336 | | |
337 | 337 | | |
338 | 338 | | |
339 | | - | |
340 | | - | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
341 | 343 | | |
342 | 344 | | |
343 | 345 | | |
344 | 346 | | |
345 | 347 | | |
346 | 348 | | |
347 | | - | |
| 349 | + | |
348 | 350 | | |
349 | 351 | | |
350 | 352 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
529 | 529 | | |
530 | 530 | | |
531 | 531 | | |
532 | | - | |
533 | | - | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
534 | 536 | | |
535 | 537 | | |
536 | 538 | | |
537 | 539 | | |
538 | 540 | | |
539 | 541 | | |
540 | | - | |
| 542 | + | |
541 | 543 | | |
542 | 544 | | |
543 | 545 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
495 | 495 | | |
496 | 496 | | |
497 | 497 | | |
498 | | - | |
499 | | - | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
500 | 502 | | |
501 | 503 | | |
502 | 504 | | |
503 | 505 | | |
504 | 506 | | |
505 | 507 | | |
506 | | - | |
| 508 | + | |
507 | 509 | | |
508 | 510 | | |
509 | 511 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
381 | 381 | | |
382 | 382 | | |
383 | 383 | | |
384 | | - | |
385 | | - | |
| 384 | + | |
| 385 | + | |
386 | 386 | | |
387 | 387 | | |
388 | 388 | | |
389 | 389 | | |
390 | 390 | | |
391 | 391 | | |
392 | | - | |
| 392 | + | |
393 | 393 | | |
394 | 394 | | |
395 | 395 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
376 | 376 | | |
377 | 377 | | |
378 | 378 | | |
379 | | - | |
380 | | - | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
381 | 383 | | |
382 | 384 | | |
383 | 385 | | |
384 | 386 | | |
385 | 387 | | |
386 | 388 | | |
387 | | - | |
| 389 | + | |
388 | 390 | | |
389 | 391 | | |
390 | 392 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
45 | 45 | | |
46 | 46 | | |
47 | 47 | | |
48 | | - | |
49 | 48 | | |
50 | 49 | | |
51 | 50 | | |
52 | 51 | | |
53 | 52 | | |
54 | 53 | | |
55 | 54 | | |
| 55 | + | |
| 56 | + | |
56 | 57 | | |
57 | 58 | | |
58 | 59 | | |
| |||
100 | 101 | | |
101 | 102 | | |
102 | 103 | | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
103 | 114 | | |
104 | 115 | | |
105 | 116 | | |
| |||
340 | 351 | | |
341 | 352 | | |
342 | 353 | | |
343 | | - | |
| 354 | + | |
344 | 355 | | |
345 | | - | |
| 356 | + | |
346 | 357 | | |
347 | 358 | | |
348 | 359 | | |
349 | 360 | | |
350 | 361 | | |
351 | 362 | | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
352 | 366 | | |
353 | 367 | | |
354 | 368 | | |
| |||
373 | 387 | | |
374 | 388 | | |
375 | 389 | | |
376 | | - | |
377 | | - | |
378 | | - | |
379 | | - | |
| 390 | + | |
380 | 391 | | |
381 | 392 | | |
382 | 393 | | |
| |||
397 | 408 | | |
398 | 409 | | |
399 | 410 | | |
400 | | - | |
401 | | - | |
402 | | - | |
403 | | - | |
404 | | - | |
405 | | - | |
406 | | - | |
407 | | - | |
408 | 411 | | |
409 | 412 | | |
410 | 413 | | |
411 | 414 | | |
412 | 415 | | |
413 | 416 | | |
| 417 | + | |
| 418 | + | |
414 | 419 | | |
415 | 420 | | |
416 | 421 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
46 | | - | |
| 46 | + | |
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
147 | 147 | | |
148 | 148 | | |
149 | 149 | | |
150 | | - | |
| 150 | + | |
151 | 151 | | |
152 | 152 | | |
153 | | - | |
| 153 | + | |
154 | 154 | | |
155 | 155 | | |
156 | 156 | | |
| |||
189 | 189 | | |
190 | 190 | | |
191 | 191 | | |
192 | | - | |
| 192 | + | |
| 193 | + | |
193 | 194 | | |
194 | 195 | | |
195 | 196 | | |
| |||
215 | 216 | | |
216 | 217 | | |
217 | 218 | | |
218 | | - | |
219 | | - | |
| 219 | + | |
220 | 220 | | |
221 | 221 | | |
222 | 222 | | |
| |||
236 | 236 | | |
237 | 237 | | |
238 | 238 | | |
239 | | - | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
240 | 256 | | |
241 | 257 | | |
242 | 258 | | |
| |||
0 commit comments