Rust性能基准测试库criterion-cpu-time的使用:精确测量CPU时间与代码执行效率

Rust性能基准测试库criterion-cpu-time的使用:精确测量CPU时间与代码执行效率

安装

在项目目录中运行以下Cargo命令:

cargo add criterion-cpu-time

或者在Cargo.toml中添加以下行:

criterion-cpu-time = "0.1.0"

示例使用

下面是一个完整的示例demo,展示如何使用criterion-cpu-time库进行性能基准测试:

use criterion::{criterion_group, criterion_main, Criterion};
use criterion_cpu_time::PosixTime;

// 定义要测试的函数
fn fibonacci(n: u64) -> u64 {
    match n {
        0 => 1,
        1 => 1,
        n => fibonacci(n - 1) + fibonacci(n - 2),
    }
}

// 使用criterion-cpu-time进行基准测试
fn bench_fib(c: &mut Criterion<PosixTime>) {
    c.bench_function("fib 20", |b| b.iter(|| fibonacci(20)));
}

// 创建基准测试组
criterion_group! {
    name = benches;
    config = Criterion::default().with_measurement(PosixTime);
    targets = bench_fib
}

// 生成main函数
criterion_main!(benches);

代码说明

  1. PosixTime 是criterion-cpu-time提供的测量类型,用于精确测量CPU时间
  2. criterion_group! 宏创建了一个基准测试组,配置了使用PosixTime测量
  3. bench_function 定义了一个具体的基准测试用例
  4. criterion_main! 宏生成main函数来运行所有基准测试

运行基准测试

运行基准测试后,criterion会提供详细的性能报告,包括:

  • 平均执行时间
  • 标准差
  • 迭代次数
  • 其他统计信息

完整示例demo

这是一个更完整的示例,展示如何测试多个函数并比较它们的性能:

use criterion::{criterion_group, criterion_main, Criterion};
use criterion_cpu_time::PosixTime;

// 定义三种不同的斐波那契数列实现

// 递归实现
fn fib_recursive(n: u64) -> u64 {
    match n {
        0 => 1,
        1 => 1,
        n => fib_recursive(n - 1) + fib_recursive(n - 2),
    }
}

// 迭代实现
fn fib_iterative(n: u64) -> u64 {
    if n == 0 || n == 1 {
        return 1;
    }
    
    let mut a = 1;
    let mut b = 1;
    
    for _ in 2..=n {
        let c = a + b;
        a = b;
        b = c;
    }
    
    b
}

// 动态规划实现(使用数组缓存)
fn fib_dynamic(n: u64) -> u64 {
    let n = n as usize;
    let mut dp = vec![1; n + 1];
    
    for i in 2..=n {
        dp[i] = dp[i - 1] + dp[i - 2];
    }
    
    dp[n]
}

// 基准测试函数
fn bench_fibs(c: &mut Criterion<PosixTime>) {
    // 测试递归实现
    c.bench_function("fib_recursive 20", |b| b.iter(|| fib_recursive(20)));
    
    // 测试迭代实现
    c.bench_function("fib_iterative 20", |b| b.iter(|| fib_iterative(20)));
    
    // 测试动态规划实现
    c.bench_function("fib_dynamic 20", |b| b.iter(|| fib_dynamic(20)));
}

// 创建基准测试组
criterion_group! {
    name = benches;
    config = Criterion::default().with_measurement(PosixTime);
    targets = bench_fibs
}

// 生成main函数
criterion_main!(benches);

注意事项

  1. 该库主要测量CPU时间,而不是墙上时钟时间
  2. 测量结果会受到系统负载的影响,建议在空闲系统上运行基准测试
  3. 对于短时间运行的函数,可能需要增加迭代次数以获得更准确的结果
  4. 测试多个实现时,确保测试环境相同,才能进行公平比较

所有者

YangKeao (YangKeao)

许可证

Apache-2.0


1 回复

Rust性能基准测试库criterion-cpu-time的使用:精确测量CPU时间与代码执行效率

criterion-cpu-time 是 Rust 生态中一个专注于精确测量 CPU 时间的性能基准测试库,它基于流行的 criterion.rs 基准测试框架,提供了更精确的 CPU 时间测量能力。

特性介绍

  • 精确测量实际 CPU 时间(而非挂钟时间)
  • 自动处理基准测试的预热和迭代
  • 提供统计分析和比较功能
  • 生成详细的 HTML 报告
  • 特别适合测量短时间运行的代码片段

安装方法

Cargo.toml 中添加依赖:

[dev-dependencies]
criterion-cpu-time = "0.4"
criterion = "0.4"

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

完整示例代码

下面是一个完整的基准测试示例,结合了基本使用和高级功能:

// benches/complete_demo.rs
use criterion_cpu_time::{black_box, Criterion, Throughput};
use std::time::Duration;

// 被测函数1: 斐波那契数列计算
fn fibonacci(n: u64) -> u64 {
    match n {
        0 => 1,
        1 => 1,
        n => fibonacci(n - 1) + fibonacci(n - 2),
    }
}

// 被测函数2: 字符串处理
fn process_string(s: &str) -> usize {
    // 模拟字符串处理
    s.chars().filter(|c| c.is_alphabetic()).count()
}

// 被测函数3: 数据处理
fn process_data(data: &[u8]) -> usize {
    // 模拟数据处理
    data.iter().map(|&x| x as usize).sum()
}

fn bench_fibonacci(c: &mut Criterion) {
    // 简单的基准测试
    c.bench_function("fibonacci 20", |b| b.iter(|| fibonacci(black_box(20))));
}

fn bench_string_processing(c: &mut Criterion) {
    // 带自定义配置的基准测试
    let mut group = c.benchmark_group("String Processing");
    
    // 配置基准测试参数
    group.sample_size(1000)
         .measurement_time(Duration::from_secs(5))
         .warm_up_time(Duration::from_secs(1));
    
    let test_string = "Hello, 这是一个测试字符串 123!";
    
    group.bench_function("count letters", |b| {
        b.iter(|| process_string(black_box(test_string)))
    });
    
    group.finish();
}

fn bench_data_processing(c: &mut Criterion) {
    // 参数化基准测试
    let sizes = [100, 1000, 10000];
    let mut group = c.benchmark_group("Data Processing");
    
    for &size in &sizes {
        let data = vec![42u8; size]; // 创建测试数据
        
        group.throughput(Throughput::Bytes(size as u64))
             .bench_with_input(format!("size_{}", size), &data, |b, data| {
                 b.iter(|| process_data(black_box(data)))
             });
    }
    
    group.finish();
}

fn bench_algorithm_comparison(c: &mut Criterion) {
    // 算法比较基准测试
    let mut group = c.benchmark_group("Algorithm Comparison");
    
    // 算法1: 快速算法
    fn fast_alg(input: u64) -> u64 {
        input * 2
    }
    
    // 算法2: 慢速算法
    fn slow_alg(input: u64) -> u64 {
        (0..input).fold(0, |acc, _| acc + 2)
    }
    
    group.bench_function("fast algorithm", |b| b.iter(|| fast_alg(black_box(1000))));
    group.bench_function("slow algorithm", |b| b.iter(|| slow_alg(black_box(1000))));
    
    group.finish();
}

// 定义基准测试组
criterion_group!(
    benches,
    bench_fibonacci,
    bench_string_processing,
    bench_data_processing,
    bench_algorithm_comparison
);

// 定义基准测试主函数
criterion_main!(benches);

运行与结果分析

  1. 运行基准测试:
cargo bench
  1. 终端输出示例:
fibonacci 20            time:   [124.56 µs 125.78 µs 127.12 µs]
count letters           time:   [156.78 ns 158.23 ns 159.89 ns]
Data Processing/size_100 time: [1.234 µs 1.245 µs 1.256 µs]
                        thrpt: [77.46 MiB/s 78.23 MiB/s 78.99 MiB/s]
Algorithm Comparison/fast time: [2.34 ns 2.35 ns 2.36 ns]
Algorithm Comparison/slow time: [4.56 µs 4.58 µs 4.60 µs]
  1. HTML 报告:
  • target/criterion 目录下生成详细的 HTML 报告
  • 包含每个基准测试的图表和统计信息
  • 提供不同实现之间的性能比较

注意事项

  1. 使用 black_box 防止编译器优化影响测量结果
  2. 对于微秒级以下的测量,考虑增加迭代次数
  3. 确保测试环境稳定,关闭不必要的后台程序
  4. 多次运行以获得更可靠的结果
  5. 注意被测函数的副作用可能影响基准测试结果

这个完整示例展示了 criterion-cpu-time 的主要功能,包括简单测量、自定义配置、参数化测试和算法比较,是进行 Rust 代码性能分析的实用起点。

回到顶部