【问题标题】:How to ignore benchmarks when not using nightly?不使用 nightly 时如何忽略基准?
【发布时间】:2016-06-07 08:53:45
【问题描述】:

我有一个包含一些基准和测试的文件,并希望针对稳定版、beta 版和 nightly 版进行测试。但是,要么我不使用基准测试,要么抱怨稳定/测试版。使用 stable/beta 时有没有办法隐藏所有基准测试部分?

book中的以下代码为例:

#![feature(test)]

extern crate test;

pub fn add_two(a: i32) -> i32 {
    a + 2
}

#[cfg(test)]
mod tests {
    use super::*;
    use test::Bencher;

    #[test]
    fn it_works() {
        assert_eq!(4, add_two(2));
    }

    #[bench]
    fn bench_add_two(b: &mut Bencher) {
        b.iter(|| add_two(2));
    }
}

我正在使用 rustup,并希望同一个文件适用于所有构建,调用类似:

rustup run nightly cargo bench --bin bench --features "bench"
rustup run nightly cargo test --bin bench --features "bench"
rustup run beta cargo test --bin bench
rustup run stable cargo test --bin bench

我能够用#![cfg_attr(feature = "bench", feature(test))] 隐藏#![feature(test)]。我可以做一些类似于其余基准部分的事情吗?什么是功能标志的好资源?

【问题讨论】:

  • 您是否尝试将基准放入他们自己的文件中(在文件夹bench 中)?
  • benches 文件夹似乎至少适用于库。我不确定如何将它与例如来自bin/bench.rs 的函数。我还发现在所有与基准相关的工作前面都写了#[cfg(feature = "bench")],并带有 ``--features "bench"` 标志。

标签: rust benchmarking


【解决方案1】:

在我的项目中,我将基准放在一个单独的模块中,就像我为测试所做的那样。然后,我创建了一个启用它们的 Cargo 功能。在这段摘录中,我使用了功能名称unstable,但您可以使用任何您喜欢的名称:

Cargo.toml

# ...

[features]
unstable = []

# ...

src/lib.rs

#![cfg_attr(feature = "unstable", feature(test))]

#[cfg(test)]
mod tests {
    #[test]
    fn a_test() {
        assert_eq!(1, 1);
    }
}

#[cfg(all(feature = "unstable", test))]
mod bench {
    extern crate test;
    use self::test::Bencher;

    #[bench]
    fn a_bench(b: &mut Bencher) {
        let z = b.iter(|| {
            test::black_box(|| {
                1 + 1
            })
        });
    }
}

#[cfg(all(feature = "unstable", test))] 行表示仅在设置了该功能并且我们在测试模式下编译时才编译以下项目。同样,#![cfg_attr(feature = "unstable", feature(test))] 仅在启用unstable 功能时启用test 功能标志。

这是一个例子in the wild

【讨论】:

    【解决方案2】:

    Cargo 支持基准测试的 benches 目录。如果你把它们放在那里,你永远不能在 beta/stable 上运行“cargo bench”,而只能在每晚运行它。

    【讨论】:

    • 该问题的 cmets 包括: benches 文件夹似乎至少适用于库。我不确定如何将它与 e.g. 一起使用。来自bin/bench.rs 的函数——也许你明白这意味着什么并且可以解决它?
    • 通常基准测试是针对特定功能的,而不是二进制文件。所以我认为这是不可行的。
    【解决方案3】:

    有没有办法在使用 stable/beta 时隐藏所有的基准测试部分?

    是的,您可以使用build script 自动执行此操作,因此在执行cargo 时无需指定--features。在构建脚本中,您可以检测 Rust 编译器的版本并定义一个功能(例如"nightly")。然后,在源代码中,您可以对基准进行分组,并在定义了功能时启用它们。

    Cargo.toml

    [package]
    build = "build.rs"
    
    [features]
    nightly = []
    
    [build-dependencies]
    rustc_version = "0.1.*"
    

    build.rs

    extern crate rustc_version;
    
    use rustc_version::{version_meta, Channel};
    
    fn main() {
        if version_meta().channel == Channel::Nightly {
            println!("cargo:rustc-cfg=feature=\"nightly\"");
        }
    }
    

    src/lib.rs

    #![cfg_attr(all(feature = "nightly", test), feature(test))]
    
    #[cfg(all(feature = "nightly", test))]
    extern crate test;
    
    pub fn add_two(a: i32) -> i32 {
        a + 2
    }
    
    #[cfg(test)]
    mod tests {
        // tests
    }
    
    #[cfg(all(feature = "nightly", test))]
    mod benchs {
        use test::Bencher;
        // benchs
    }
    

    【讨论】:

      猜你喜欢
      • 2011-07-31
      • 1970-01-01
      • 1970-01-01
      • 2021-01-23
      • 2018-09-23
      • 2020-08-28
      • 2011-10-03
      • 2022-01-14
      • 1970-01-01
      相关资源
      最近更新 更多