Skip to content

bench: measure render cost across setups and inputs - #617

Closed
lessthanjacob wants to merge 1 commit into
mainfrom
js/engine-bench-main
Closed

lessthanjacob wants to merge 1 commit into
mainfrom
js/engine-bench-main

Conversation

@lessthanjacob

Copy link
Copy Markdown
Contributor

Checklist:

  • I have updated the necessary documentation
  • I have signed off all my commits as required by DCO
  • My build is green

Why

rake benchmarks only enforces a few throughput floors. A render-path change can get slower and still pass CI. rake engines is the comparison to put in a render-path PR: one factor at a time, then a few combined profiles, with the change against a saved main run.

What

  • bundle exec rake engines (spec/benchmarks/engines/). V1 on this branch. When Blueprinter::V2 is defined, the same run also measures V2 and V2+Legacy.
  • Before timing, each scenario is rendered on every engine and an engine whose output differs is dropped, with the reason listed.
  • BASELINE=<results json> prints the change in median time and allocations per rendered object.
  • Results are written to benchmarks/results/ (gitignored). LIST=1 prints the sweep names.
  • AGENTS.md and docs/testing.md tell render-path changes to report this comparison. rake benchmarks still has to pass.

Not run in CI.

Check

Smoke-tested on this machine with LIST=1 and SWEEPS=input_kind SAMPLES=1 (V1 only, YJIT off). Full bundle exec rake was not run locally.

Made with Cursor

rake benchmarks only enforces a few throughput floors, so a render-path
change can get slower and still pass CI. rake engines varies one factor
at a time (input kind, size, nesting, fields, extensions, and so on),
checks that engines agree before timing, and prints the change against
a saved run via BASELINE=.

On main it measures V1. When Blueprinter::V2 is defined it also measures
V2 and V2+Legacy. Results go to benchmarks/results/, which is gitignored.

Signed-off-by: Jacob Sheehy <jacobjsheehy@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
def table(axis, rows)
head = [axis, 'engine', 'median ms', 'time', 'alloc/obj', 'alloc']
["| #{head.join(' | ')} |", "|#{head.map { ' --- |' }.join}",
*rows.map { |r| "| #{r.map { |c| c.to_s.gsub('|', '\\|') }.join(' | ')} |" }]
end

def md_table(head, rows)
cells = ->(row) { row.map { |c| c.to_s.gsub('|', '\\|') }.join(' | ') }
@lessthanjacob

Copy link
Copy Markdown
Contributor Author

Closing for now. This is not ready for review yet.

@lessthanjacob
lessthanjacob deleted the js/engine-bench-main branch October 27, 2026 01:32
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.

2 participants