【问题标题】:Why is running cargo bench faster than running release build?为什么运行 cargo bench 比运行 release build 快?
【发布时间】:2021-04-18 01:28:52
【问题描述】:

我想对我的 Rust 程序进行基准测试,并且正在比较一些替代方案来做到这一点。然而,我注意到,当使用cargo benchbencher crate 运行基准测试时,代码的运行速度始终比使用相同代码运行生产构建 (cargo build --release) 时更快。例如:

主要代码:

use dot_product;
const N: usize = 1000000;

use std::time;
fn main() {
    let start = time::Instant::now();
    dot_product::rayon_parallel([1; N].to_vec(), [2; N].to_vec());
    println!("Time: {:?}", start.elapsed());
}

平均时间:~20ms

基准代码:

#[macro_use]
extern crate bencher;

use dot_product;

use bencher::Bencher;

const N: usize = 1000000;

fn parallel(bench: &mut Bencher) {
    bench.iter(|| dot_product::rayon_parallel([1; N].to_vec(), [2; N].to_vec()))
}

benchmark_group!(benches, sequential, parallel);
benchmark_main!(benches);

时间:5,006,199 ns/iter (+/- 1,320,975)

我对其他一些程序进行了同样的尝试,cargo bench 始终提供更快的结果。为什么会发生这种情况?

【问题讨论】:

  • 因为你的基准测试什么都不做。
  • bench.iter(|| black_box(dot_product::rayon_parallel([1; N].to_vec(), [2; N].to_vec())))
  • 你检查std::time的分辨率了吗?
  • 有效,但实际上必须对 [1; N] 部分进行黑盒处理。谢谢!
  • @danitrod 你能尝试运行你的原始代码 1000 次并计算它需要多少吗? Benchers 运行代码很多次,然后将总时间除以迭代次数。

标签: rust benchmarking


【解决方案1】:

按照 cmets 的建议,您应该在基准测试代码中的所有(最终)结果上使用 criterion::black_box()。这个函数什么都不做 - 只是返回它唯一的参数 - 但对优化器是不透明的,所以编译器必须假设函数对输入做了 something

当不使用black_box() 时,基准测试代码实际上不会做任何事情,因为编译器能够确定您的代码的结果未被使用并且不会观察到任何副作用。因此,它会在消除死代码期间删除您的所有代码,而您最终进行基准测试的是基准测试套件本身。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-22
    • 2015-10-27
    • 1970-01-01
    • 2021-09-27
    • 2021-08-26
    • 1970-01-01
    相关资源
    最近更新 更多