What Output Formats Does nanobench Support?
Updated
nanobench supports four built-in output formats—CSV, JSON, HTML box plots, and Python's pyperf format—plus custom rendering through Mustache-like templates. You get these by calling render() on a benchmark result or comparison result and passing a template from the ankerl::nanobench::templates namespace. The default console output is a table whose columns you can control; the template formats are for feeding results into other tools or reports.
Default table output and column control
When you run a benchmark without rendering a template, nanobench prints a table. The documentation lists these columns: relative, complexityN, timePerUnit, unitPerSecond, error, instructions, cycles, ipc, branches, branchMisses, total, and _size.
You can shape this table with hideColumn(), showColumn(), and isColumnVisible(). Context values can also be promoted into their own columns via contextColumn() and clearContextColumns(), which is useful when you sweep a parameter and want each value visible per row.
Built-in templates
All built-in templates live in ankerl::nanobench::templates and are passed to render():
| Template | Function | Typical use |
|---|---|---|
| CSV | templates::csv / csv() |
Spreadsheet import, diffing runs |
| JSON | templates::json / json() |
Storing results, downstream tooling |
| HTML box plot | templates::htmlBoxplot / htmlBoxplot() |
Visualizing run-to-run spread |
| pyperf | templates::pyperf / pyperf() |
Consuming results with Python's pyperf module |
The documentation also covers CSV specifically for comparisons ("CSV for a comparison") and a section on how precise a comparison is, so if you plan to compare alternatives, read those before trusting small differences.
Rendering a result
The pattern is: run the benchmark, keep the Result, then render it with a template. Conceptually:
ankerl::nanobench::Bench b;
b.title("example").unit("op");
b.run("something fast", [&] { /* work */ });
// Render the most recent result
ankerl::nanobench::render(ankerl::nanobench::templates::json(), b.results());
Bench::results() returns the collected Result objects, and render() accepts a template plus results. For comparisons, CompareResult has its own render() overload, so you render the comparison outcome rather than individual results.
Custom Mustache-like templates
Beyond the built-ins, render() accepts Mustache-like templates, so you can produce any text format—Markdown tables, custom logs, config fragments—by writing a template with placeholders. The documentation's "Rendering" and "Mustache-like Templates" sections describe the syntax, and "Time Units in Templates" explains how time values are formatted inside templates. If you need a unit other than the default in your output, set it with timeUnit() on the bench or handle it in the template.
Practical notes
- Comparisons need the comparison path. Use
compare()and render the resultingCompareResult;isSignificant()andfastest()tell you whether a difference is meaningful before you publish it. - CSV and JSON are the safe interchange formats. If another tool will read the output, prefer these over scraping the console table.
- Box plots need multiple rounds. The HTML box plot template is only informative when the benchmark ran enough epochs to show spread; check
epochs()and related settings if the plot looks degenerate. - pyperf output targets Python tooling. Use it when your analysis pipeline already uses the pyperf module; otherwise JSON is more general.
For exact template names, placeholder syntax, and the comparison-specific CSV behavior, consult the corresponding sections of the nanobench documentation, since the API reference lists each template function individually.