Generate markdown comparison tables from Cargo Criterion benchmark output.
Currently, the tool is limited to Github Flavored Markdown (GFM), but adding new output types is simple.
```bash
cargo install cargo-criterion
cargo install criterion-table ```
/
)
<table_name>/<column_name>/[row_name]
benchmark_function
you would only get a column
name, which isn't validBenchmarkId
you will get all three
sections automatically```rust use criterion::{blackbox, criteriongroup, criterion_main, Criterion};
fn fibonacci(n: u64) -> u64 { match n { 0 => 1, 1 => 1, n => fibonacci(n-1) + fibonacci(n-2), } }
pub fn criterionbenchmark(c: &mut Criterion) { let id = "Fibonacci/Recursive Fib/20"; c.benchfunction(id, |b| b.iter(|| fibonacci(black_box(20)))); }
criteriongroup!(benches, criterionbenchmark); criterion_main!(benches); ```
```rust use criterion::{blackbox, BenchmarkId, criteriongroup, criterion_main, Criterion};
fn fibonacci(n: u64) -> u64 { match n { 0 => 1, 1 => 1, n => fibonacci(n-1) + fibonacci(n-2), } }
pub fn criterionbenchmark(c: &mut Criterion) { let mut group = c.benchmarkgroup("Fibonacci");
for row in vec![10, 20] {
let id = BenchmarkId::new("Recursive Fib", row);
group.bench_with_input(id, &row, |b, row| {
b.iter(|| fibonacci(black_box(*row)))
});
}
group.finish();
}
criteriongroup!(benches, criterionbenchmark); criterion_main!(benches); ```
This can be done in a couple of different ways:
This method ensures all benchmarks are included in one step
```bash
cargo criterion --message-format=json | criterion-table > BENCHMARKS.md ```
This method allows better control of order and which benchmarks are included
```bash
cargo criterion --bench recursivefib --message-format=json > recursivefib.json cargo criterion --bench iterativefib --message-format=json > iterativefib.json
cat iterativefib.json recursivefib.json | criterion-table > BENCHMARKS.md ```
Currently, the tool is hardcoded to GFM, but it is easy to add a new output
type via the Formatter
trait by creating your own new binary project
toml
[dependencies]
criterion-table = "0.1"
criterion_table::Formatter
```rust use criterion_table::{ColumnInfo, Comparison, TimeUnit}; use flexstr::FlexStr;
pub trait Formatter { fn start(&mut self, buffer: &mut String, tables: &[&FlexStr]);
fn end(&mut self, buffer: &mut String);
fn start_table(&mut self, buffer: &mut String, name: &FlexStr, columns: &[ColumnInfo]);
fn end_table(&mut self, buffer: &mut String);
fn start_row(&mut self, buffer: &mut String, name: &FlexStr, max_width: usize);
fn end_row(&mut self, buffer: &mut String);
fn used_column(&mut self, buffer: &mut String, time: TimeUnit, pct: Comparison, max_width: usize);
fn unused_column(&mut self, buffer: &mut String, max_width: usize);
} ```
process
function that takes cargo-criterion
raw JSON as
input and outputs your format as a String
:NOTE: Replace GFMFormatter
with your new formatter below
```rust use std::error::Error; use std::io::Read;
// This would be replaced with your formatter use criteriontable::formatter::GFMFormatter; use criteriontable::{CriterionTableData, RawCriterionData};
fn process(r: impl Read) -> Result
// Pass your formatter to `make_tables` below
Ok(data.make_tables(GFMFormatter))
} ```
String
to the file type of your formatterThis project is licensed optionally under either: