在 Rust 中使用 Brainfuck 解释器工作时,我注意到当基准包含大型类型时,
cargo bench
需要非常长的时间来构建 Criterion 工作台。
作为 Brainfuck 实现的一部分,我定义了一个具有非常大数组的结构来充当解释器内存。当我使用
cargo build --release
进行编译时,我的 crate 在几秒钟内即可构建完成,但是当我运行 cargo bench
时,构建需要 6 分钟以上!我最终意识到这与我的类型定义中的非常大的数组有关([u8; 30_000]
)。我认为我可以通过间接方式使类型更小,因此我将类型更改为 Box<[u8; 30_000]>
,这确实显着减少了基准测试的构建时间。
我的问题是:为什么
cargo bench
的构建时间比没有 cargo build --release
的 Box<>
花费的时间要长得多,它们不应该使用相同的优化级别吗?为什么在没有 cargo build --release
的情况下 Box<>
不需要那么长的时间?
这可能是 Criterion 的一个错误吗?
我通过
cargo bench --no-run --timings
确认,几乎所有时间都花在建造长凳本身上。我还制作了一个最小的可重现示例:
cargo --version
> cargo 1.64.0 (387270bc7 2022-09-16)
[package]
name = "large-type"
version = "0.1.0"
edition = "2021"
[dev-dependencies]
criterion = "0.4.0"
[[bench]]
name = "my_benches"
harness = false
pub struct MyType {
data: [u8; 30_000],
}
impl MyType {
pub fn new() -> Self {
MyType { data: [0; 30_000] }
}
}
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use large_type::MyType;
pub fn my_test(c: &mut Criterion) {
c.bench_function("my test", |b| b.iter(|| black_box(MyType::new())));
}
criterion_group!(benches, my_test);
criterion_main!(benches);
$ cargo build --release
Compiling large-type v0.1.0 (C:\Users\myuser\large-type)
Finished release [optimized] target(s) in 0.22s
$ cargo bench --no-run
...
...
Compiling large-type v0.1.0 (C:\Users\myuser\large-type)
Finished bench [optimized] target(s) in **3m 46s**
大约 15 秒用于编译 Criterion 依赖项和我的库,其余时间用于
Executable benches\my_benches.rs
。
最后,当我将
[u8; 30_000]
更改为 Box<[u8; 30_000]>
时,cargo build --release
和 cargo bench --no-run
都在非常合理的时间内完成。有什么想法吗?
编辑:我认为拳击是一个合适的解决方案,但我想尽可能避免性能受到影响,并理解为什么两个版本之间会有差异。
您发布的
cargo build
命令不会构建基准。
# Does not build benchmarks
cargo build --release
如果您想使用
cargo build
构建基准,您需要使用 --all-targets
(或 --benches
)
cargo build --release --all-targets