使用criterion库时,如何让cargo bench输出log crate日志?
解决Criterion基准测试中log crate日志无输出的问题
核心原因
Criterion默认会捕获并隐藏基准测试过程中的标准输出/错误流,且log crate需要正确初始化日志后端才能输出,仅设置RUST_LOG不足以生效。
具体解决步骤
1. 添加必要依赖
在Cargo.toml中添加日志后端(以env_logger为例),并确保criterion依赖正常配置:
[dependencies] criterion = "0.5" log = "0.4" env_logger = "0.10"
2. 提前初始化日志后端
在基准测试代码文件(如benches/my_benchmark.rs)的最顶部,Criterion分组定义之前完成日志初始化:
use criterion::{criterion_group, criterion_main, Criterion}; use log::warn; use env_logger::Builder; use std::io::Write; // 初始化日志,确保在Criterion启动前执行 fn init_logger() { Builder::new() .format(|buf, record| writeln!(buf, "[{}] {}", record.level(), record.args())) .filter_level(log::LevelFilter::Warn) .init(); } fn my_benchmark(c: &mut Criterion) { warn!("Please warn"); println!("Please print"); // 你的基准测试逻辑 c.bench_function("my_test", |b| b.iter(|| { /* 测试代码 */ })); } init_logger(); criterion_group!(benches, my_benchmark); criterion_main!(benches);
3. 正确执行基准测试命令
执行时需设置RUST_LOG,并将--nocapture参数放在--之后(传递给测试运行时而非cargo):
RUST_LOG=warn cargo bench --bench my_benchmark -- --nocapture
额外注意事项
- 若使用其他日志后端(如
simple_logger),初始化逻辑类似,核心是在Criterion启动前完成配置 - 如果日志在
iter闭包内,需用std::hint::black_box包裹相关代码,避免被编译器优化剔除 - 检查
RUST_LOG的级别设置是否匹配日志语句的级别(比如warn!对应RUST_LOG=warn及以上级别)
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

