如何在 Rust 中测量性能:面向初学者的基准测试指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

为什么 Rust 需要特殊的基准测试方法?



Rust 以其速度著称,但即使是最快的语言,糟糕的实现也会拖慢它。您是否曾经编写过一段 Rust 算法,心想:“这肯定会快如闪电!”,然后运行起来却不明白——微秒都浪费在哪里了?熟悉吗?



Rust 中的基准测试不仅仅是启动计时器和测量时间。这是一门科学:需要考虑编译器优化、CPU 缓存,甚至 Rust 管理内存的方式。在本文中,我们将探讨如何正确地对 Rust 程序进行基准测试,以便您获得真实的数据,而不是随机的结果。



我们将从使用 std::time 的简单测量开始,一直到专业工具 criterion(实际项目中使用的工具)。开始吧!



1. 最简单的方法:std::time::Instant



如果您想快速“感受”一段代码的性能——无需安装任何 crate,只需将测量代码直接插入 main 函数即可。但有一个陷阱:如果您的代码没有使用其结果,Rust 优化器可能会“丢弃”它。



use std::time::Instant;

fn main() { let start = Instant::now();

// 您需要测量的代码 let mut sum = 0u64; for i in 0..1_000_000 { sum += i; }

let duration = start.elapsed(); println!("执行时间: {:?}", duration); // 务必使用结果! println!("总和: {}", sum);}


为什么不能只测量一次运行?

单次运行就像抽奖。系统可能正忙,CPU 可能降频,缓存可能是冷的。Rust 中正确的基准测试应该:

  • 预热代码 (warm-up) —— 在测量前进行几次迭代
  • 多次运行代码(数千次迭代)
  • 对结果取平均值


手动实现这些很容易出错。因此,Rust 社区发明了 criterion。



2. 专业基准测试:Criterion crate



Criterion.rs 是 Rust 中基准测试的事实标准。它被用于编译器 rustc 本身以及数百个 crate 中。它为什么这么棒?

  • 自动预热和统计处理
  • 图表以及与之前运行结果的比较
  • 检测性能回归(如果代码变慢,您会知道)
  • 支持参数化基准测试


安装与配置

在 Cargo.toml 中添加:

[dev-dependencies]criterion = { version = "0.5", features = ["html_reports"] }

[[bench]]name = "my_benchmark"harness = false


创建文件 benches/my_benchmark.rs:



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

// 被基准测试的函数fn fibonacci(n: u64) -> u64 { match n { 0 => 0, 1 => 1, _ => fibonacci(n - 1) + fibonacci(n - 2), }}

fn bench_fibonacci(c: &mut Criterion) { c.bench_function("fibonacci 20", |b| { // black_box — 阻止优化器丢弃代码 b.iter(|| fibonacci(black_box(20))) });}

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


运行:cargo bench。您将看到类似这样的输出:

fibonacci 20             time:   [24.567 µs 24.789 µs 25.012 µs]


三个数字是置信区间(下限、平均值、上限)。如果区间很窄,说明基准测试稳定。



3. 秘密武器:black_box



您可能注意到了示例中的 black_box。这是 criterion 中的一个神奇函数,它阻止 LLVM 优化参数或结果。没有它,您的基准测试可能显示 0 纳秒——因为编译器在编译阶段就直接计算出了常量。



示例 p

博客

书籍推荐