5 个版本 (重大变更)

0.5.0 2024年4月19日
0.4.0 2024年2月3日
0.3.0 2024年1月25日
0.2.0 2023年12月6日
0.1.0 2023年10月29日

#37 in 性能分析

Download history 483/week @ 2024-04-25 1031/week @ 2024-05-02 1226/week @ 2024-05-09 1196/week @ 2024-05-16 1084/week @ 2024-05-23 1011/week @ 2024-05-30 886/week @ 2024-06-06 859/week @ 2024-06-13 1024/week @ 2024-06-20 864/week @ 2024-06-27 922/week @ 2024-07-04 782/week @ 2024-07-11 747/week @ 2024-07-18 1158/week @ 2024-07-25 672/week @ 2024-08-01 524/week @ 2024-08-08

每月下载 3,198
nu 中使用

MIT 许可证

84KB
2K SLoC

Tango.rs

Tango Bench Tango Bench

过去,基准测试需要大量时间和多次迭代才能获得有意义的成果,尤其是在尝试检测细微变化(如几个百分点范围内的变化)时尤为困难。

介绍 Tango.rs,这是一个创新的基准测试框架,它使用成对基准测试来评估代码性能。这种方法利用了这样一个事实:测量两个同时执行的功能之间的性能差异比测量两个依次执行的功能之间的性能差异要高效得多。

特性

  • 对变化的极高敏感性,使得结果比传统的(点对点)方法更快收敛。通常,一秒钟的时间就足够了;
  • 能够比较来自不同版本控制系统的同一代码的不同版本(A/B基准测试);
  • 支持 macOS、Linux 和 Windows;

1 秒钟,1%,1 个错误

与传统点对点基准测试相比,成对基准测试对变化的敏感性更高。这种增强的敏感性使得可以提前检测到统计上显著的性能变化。

Tango 设计用于在至少 9 次测试运行中有 1 次能够在 1 秒内检测到 1% 的性能变化。

先决条件

  1. 已安装 Rust 和 Cargo 工具链(Linux/macOS 上支持 Rust 稳定版本,Windows 需要夜间版本)
  2. (可选) 已安装 cargo-export

入门

  1. 添加 cargo 依赖项并创建新的基准测试

    [dev-dependencies]
    tango-bench = "0.5"
    
    [[bench]]
    name = "factorial"
    harness = false
    
  2. 允许 rustc 从基准测试中导出符号以进行动态链接

    • (Linux/macOS) 添加构建脚本 (build.rs),内容如下

      fn main() {
          println!("cargo:rustc-link-arg-benches=-rdynamic");
          println!("cargo:rerun-if-changed=build.rs");
      }
      
    • (Windows,需要夜间版本) 将以下代码添加到 cargo 配置文件 (.cargo/config)

      [build]
      rustflags = ["-Zexport-executable-symbols"]
      
  3. 添加 benches/factorial.rs,内容如下

    use std::hint::black_box;
    use tango_bench::{benchmark_fn, tango_benchmarks, tango_main, IntoBenchmarks};
    
    pub fn factorial(mut n: usize) -> usize {
        let mut result = 1usize;
        while n > 0 {
            result = result.wrapping_mul(black_box(n));
            n -= 1;
        }
        result
    }
    
    fn factorial_benchmarks() -> impl IntoBenchmarks {
        [
            benchmark_fn("factorial", |b| b.iter(|| factorial(500))),
        ]
    }
    
    tango_benchmarks!(factorial_benchmarks());
    tango_main!();
    
  4. 构建并将基准测试导出到 target/benchmarks 目录

    $ cargo export target/benchmarks -- bench --bench=factorial
    
  5. 现在让我们尝试修改 factorial.rs 并使阶乘更快 :)

    fn factorial_benchmarks() -> impl IntoBenchmarks {
        [
            benchmark_fn("factorial", |b| b.iter(|| factorial(495))),
        ]
    }
    
  6. 现在我们可以比较新版本和已经构建的版本

    $ cargo bench -q --bench=factorial -- compare target/benchmarks/factorial
    factorial             [ 375.5 ns ... 369.0 ns ]      -1.58%*
    

结果显示,确实存在大约1%的差异,即 factorial(500)factorial(495) 之间的差异。

更多的示例可以在 examples 目录中找到。

运行器参数

你可以向 compare 命令传递几个参数来改变其行为

  • -t--time – 每个基准运行多长时间(以秒为单位)
  • s--samples – 从每个基准收集多少样本
  • -f – 通过名称过滤基准。支持通配符模式(例如 */bench_name/{2,4,8}/**
  • o--filter-outliers – 额外过滤异常值
  • --fail-threshold – 如果新版本在给定百分比上比基线慢,则失败
  • --fail-fast - 在第一个超出失败阈值的基准之后失败,而不是在整套测试之后

贡献

项目处于早期阶段,所以任何帮助都将受到欢迎。以下是一些你可能感兴趣的想法

  • 找到一种为注册系统中的函数提供更用户友好的API的方法
  • 如果你是库的作者,尝试tango并提供反馈将非常有用

依赖项

~2–11MB
~129K SLoC