#markdown-tables #benchmark #generate-markdown #markdown #criterion

bin+lib criterion-table

从 cargo-criterion 基准输出中生成 markdown 对比表格

9 个不稳定版本 (3 个破坏性更新)

0.4.2 2022年3月15日
0.4.1 2022年3月14日
0.3.0 2022年3月13日
0.2.2 2022年3月12日
0.1.1 2022年3月11日

#212 in 性能分析

每月28次下载

MIT/Apache

29KB
608

criterion-table

Crate Docs

Cargo Criterion 基准 JSON 输出中生成 markdown 对比表格。

目前,此工具仅限于 GitHub Flavored Markdown (GFM),但添加新的输出类型相对简单。

生成的 Markdown 示例

非常基础的报告

FlexStr 基准报告

安装

# If you don't have it already
cargo install cargo-criterion

# This project
cargo install criterion-table

使用方法

  1. 确保你的基准测试满足以下基本标准
  • 基准测试 ID 以两个到三个部分组成,由斜杠分隔(/
    • 这些部分的使用方式如下: <table_name>/<column_name>/[row_name]
    • 目前没有更改大小写,因此请适当地设置以供显示
    • 行名称是唯一可选字段,如果留空,所有结果将是一个空行
    • 如果使用非常基础的 benchmark_function,则默认只会获得列名称,这不足以
    • 如果使用基准测试组,您将自动获得两个部分
    • 如果使用基准测试组和 BenchmarkId,您将自动获得所有三个部分
  • 基准测试数据不会重新排序,因此请确保它们以所需的顺序执行
    • 表格根据它们在数据中看到的顺序(执行顺序)排序
    • 每行的第一列将是基准测试的基准,该行中的其他所有内容都将与之比较,因此基准测试执行顺序很重要

基准测试示例 1 - 手动 ID

use criterion::{black_box, criterion_group, criterion_main, Criterion};

#[inline]
fn fibonacci(n: u64) -> u64 {
  match n {
    0 => 1,
    1 => 1,
    n => fibonacci(n-1) + fibonacci(n-2),
  }
}

pub fn criterion_benchmark(c: &mut Criterion) {
    let id = "Fibonacci/Recursive Fib/20";
    c.bench_function(id, |b| b.iter(|| fibonacci(black_box(20))));
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);

基准测试示例 2 - 带参数的基准测试组

use criterion::{black_box, BenchmarkId, criterion_group, criterion_main, 
                Criterion};

#[inline]
fn fibonacci(n: u64) -> u64 {
  match n {
    0 => 1,
    1 => 1,
    n => fibonacci(n-1) + fibonacci(n-2),
  }
}

pub fn criterion_benchmark(c: &mut Criterion) {
    let mut group = c.benchmark_group("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();
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
  1. 创建一个 tables.toml 配置文件(可选

这允许你添加注释以与 markdown 中的表格集成。表名称为小写,空格用连字符替换。文件必须在本地目录中。以下是一个示例

[top_comments]
Overview = """
This is a benchmark comparison report.
"""

[table_comments]
fibonacci = """
Since `fibonacci` is not tail recursive or iterative, all these function calls 
are not inlined which makes this version very slow.
"""
  1. 运行基准测试并生成 Markdown

这可以通过几种不同的方式完成

单步操作

此方法确保所有基准测试都在一步内完成

# Run all benchmarks and convert into the markdown all in one step
cargo criterion --message-format=json | criterion-table > BENCHMARKS.md

多步操作

此方法允许更好地控制顺序和包含哪些基准测试

# Execute only the desired benchmarks
cargo criterion --bench recursive_fib --message-format=json > recursive_fib.json
cargo criterion --bench iterative_fib --message-format=json > iterative_fib.json

# Reorder before converting into markdown
cat iterative_fib.json recursive_fib.json | criterion-table > BENCHMARKS.md

添加新的输出文件类型

目前,工具硬编码为GFM,但可以通过创建自己的新二进制项目,通过Formatter特质轻松添加新的输出类型

  1. 将此crate,FlexStr,和IndexMap添加到您的二进制项目中
[dependencies]
criterion-table = "0.4"
flexstr = "0.8"
indexmap = "1"
  1. 创建一个新类型并实现Formatter

  2. 创建一个main函数并调用build_tables

注意:将下面的GFMFormatter替换为您的新格式化器

use std::io;

use criterion_table::build_tables;
// Replace with your formatter
use criterion_table::formatter::GFMFormatter;

const TABLES_CONFIG: &str = "tables.toml";

fn main() {
    // Replace `GFMFormatter` with your formatter
    match build_tables(io::stdin(), GFMFormatter, TABLES_CONFIG) {
        Ok(data) => {
            println!("{data}");
        }
        Err(err) => {
            eprintln!("An error occurred processing Criterion data: {err}");
        }
    }
}
  1. 将返回的String保存到格式化器的文件类型或写入stdout

许可证

该项目可选择以下任一许可证进行许可

依赖项

~2–3MB
~58K SLoC