bencher.render
Out-of-process rendering for benchmark results.
This module is the render half of bencher’s collect/render split. The
collect half (bencher.Bench.collect(), i.e. plot_sweep(auto_plot=False))
runs a sweep and computes regression detection without building any
holoviews/panel/bokeh objects, returning a fully-populated BenchResult.
Why split: holoviews/panel/bokeh build large object graphs backed by
C-extension wrappers (param, pandas, bokeh). When CPython’s cyclic garbage
collector traverses those wrappers while foreign live C-extension state
exists in the same interpreter (e.g. ROS 2 rclpy/DDS), the process can
segfault. Rendering from a persisted result in a separate, clean process
(one that never imported the foreign extension) makes that class of crash
impossible by construction.
Typical usage:
# Process 1 — holds rclpy/DDS; never builds plots:
res = bench.collect(...) # auto_plot=False under the hood
bencher.save_result(res, "result.pkl")
# Process 2 — clean (only imports bencher), e.g. spawned via:
# python -m bencher.render result.pkl output_dir
bencher.render_report("result.pkl", "output_dir")
render_report is also importable for in-process use when isolation is not
required.
Attributes
Functions
|
Persist a collected |
|
Load a |
|
Render a collected result to an HTML report. |
|
CLI entrypoint: |
Module Contents
- bencher.render.logger
- bencher.render.save_result(bench_res: bencher.results.bench_result.BenchResult, path: str | pathlib.Path) pathlib.Path
Persist a collected
BenchResultto path via pickle.Mirrors how bencher already caches results internally: the (potentially non-pickleable)
object_indexis stripped before writing and restored afterwards, so the live object is unchanged.- Parameters:
bench_res – A result from
Bench.collect()/plot_sweep.path – Destination file path.
- Returns:
The path written.
- bencher.render.load_result(path: str | pathlib.Path) bencher.results.bench_result.BenchResult
Load a
BenchResultpreviously written bysave_result().
- bencher.render.render_report(result_or_path: bencher.results.bench_result.BenchResult | str | pathlib.Path, output_dir: str | pathlib.Path, *, report: bencher.bench_report.BenchReport | None = None, filename: str | None = None, in_html_folder: bool = False, portable: bool = False) pathlib.Path
Render a collected result to an HTML report.
Reconstructs the holoviews/panel report from a result produced by
Bench.collect()(or a path to one saved withsave_result()) and writes it under output_dir. This is the only step that constructs plotting objects, and it is designed to run in a process free of foreign C-extension state.The result already carries its
regression_report(computed during collection), so no sweep re-execution happens here.- Parameters:
result_or_path – A
BenchResult, or a path to a saved one.output_dir – Directory to write the report into.
report – An existing
BenchReportto append to. A new one is created (named after the benchmark) when omitted.filename – Output HTML filename. Defaults to
<bench_name>.html.in_html_folder – Forwarded to
BenchReport.save().portable – Forwarded to
BenchReport.save()(base64-inline assets).
- Returns:
The path to the saved report.
- bencher.render.main(argv: list[str] | None = None) int
CLI entrypoint:
python -m bencher.render <result_path> <output_dir>.