第34章 cargo bench 基准测试命令详解
名称
cargo-bench — 执行包的基准测试
概要
cargo bench [选项] [benchname] [-- bench 选项]
描述
编译并执行基准测试。
基准测试过滤参数 benchname,以及双横线(--)之后的所有参数,都会传给基准测试二进制文件,也就是 libtest(rustc 内置的单元测试和微基准测试框架)。如果需要同时给 Cargo 和二进制文件传参数,-- 之后的参数会传给二进制文件,之前的则传给 Cargo。关于 libtest 参数的详细信息,可以运行 cargo bench -- --help 查看,或阅读 rustc book 中关于测试工作原理的章节:https://doc.rust-lang.org/rustc/tests/index.html。
例如,下面的命令只运行名为 foo 的基准测试(跳过 foobar 等名称相近的其他基准测试):
cargo bench -- foo --exact
基准测试以 --test 选项传给 rustc 编译,这样会把你的代码与 libtest 链接成一个特殊的可执行文件。该可执行文件会自动运行所有标注了 #[bench] 属性的函数。Cargo 还会向测试工具传递 --bench 标志,告诉它只运行基准测试——无论测试工具是 libtest 还是自定义实现。
可以在 target 的 manifest 配置中设置 harness = false 来禁用 libtest 测试工具,此时你的代码需要自己提供 main 函数来运行基准测试。
注意:
#[bench]属性目前尚不稳定,只能在 nightly 渠道使用。crates.io 上有一些包可以帮助你在 stable 渠道运行基准测试,例如 Criterion。
默认情况下,cargo bench 使用bench 配置文件,该配置启用了优化并禁用了调试信息。如果需要调试基准测试,可以使用 --profile=dev 命令行选项切换到 dev 配置文件,然后在调试器中运行启用了调试的基准测试。
基准测试的工作目录
每个基准测试的工作目录都设置为所属包根目录。这样设置可以让基准测试通过相对路径可靠地访问包内的文件,而无需关心 cargo bench 是在哪里执行的。
选项
基准测试选项
--no-run-
只编译,不运行基准测试。
--no-fail-fast-
无论失败与否,运行所有基准测试。如果没有此标志,Cargo 会在第一个可执行文件失败后退出。Rust 测试框架会运行该可执行文件内的所有基准测试直至完成,此标志仅针对整个可执行文件起作用。
包选择
默认情况下,如果未指定包选择选项,所选包取决于选定的清单文件(若未指定 --manifest-path,则基于当前工作目录)。如果该清单是工作区的根,则选择工作区的默认成员;否则,仅选择由该清单定义的包。
可以在根清单中的 workspace.default-members 键中显式设置工作区的默认成员。如果未设置,虚拟工作区将包含所有工作区成员(等同于传入 --workspace),而非虚拟工作区则仅包含根 crate 本身。
-pspec…--packagespec…-
只对指定的包进行基准测试。SPEC 格式参见 cargo-pkgid(1)。此标志可多次指定,并支持
*、?、[]等常见的 Unix glob 模式。但为了避免 shell 在 Cargo 处理之前误展开这些模式,每个模式都必须用单引号或双引号包起来。 --workspace-
对 workspace 中的所有成员进行基准测试。
--all-
--workspace的弃用别名。 --excludeSPEC…-
排除指定的包,必须与
--workspace标志一起使用。此标志可多次指定,并支持*、?、[]等常见的 Unix glob 模式。但为了避免 shell 在 Cargo 处理之前误展开这些模式,每个模式都必须用单引号或双引号包起来。
Target 选择
如果没有指定任何 target 选择选项,cargo bench 会构建所选包的以下 target:
- lib —— 用于与二进制和 benchmark 链接
- bins(仅当需要构建 benchmark target 且所需 feature 已启用时)
- 作为 benchmark 的 lib
- 作为 benchmark 的 bins
- benchmark target
可以通过在清单配置中为目标设置 bench 标志来改变默认行为。将示例设置为 bench = true 会把该示例作为基准测试来构建和运行,并用 libtest 测试框架替换示例的 main 函数。
将目标设置为 bench = false 可以让它默认不被基准测试。通过名称指定目标的选项(如 --example foo)会忽略 bench 标志,始终对指定的目标进行基准测试。
关于按目标配置的更多信息,请参阅配置目标(Configuring a target)。
如果选择了某个集成测试或基准测试,其二进制目标会被自动构建。这样集成测试就可以执行该二进制文件来检验和测试其行为。集成测试在构建和运行时会设置 CARGO_BIN_EXE_<name> 环境变量,以便通过 env 宏或 var 函数来定位可执行文件。
传入目标选择标志时,只会对指定的目标进行基准测试。
注意 --bin、--example、--test 和 --bench 标志也支持 *、?、[] 等常见的 Unix glob 模式。但为了避免 shell 在 Cargo 处理之前就展开 glob 模式,必须用单引号或双引号把每个 glob 模式包起来。
--lib-
对包的库进行基准测试。
--binname…-
对指定的二进制目标进行基准测试。该标志可以多次指定,并支持常见的 Unix glob 模式。
--bins-
对所有二进制目标进行基准测试。
--examplename…-
对指定的示例进行基准测试。此标志可多次指定,并支持常见的 Unix glob 模式。
--examples-
对所有示例目标进行基准测试。
--testname…-
对指定的集成测试进行基准测试。此标志可多次指定,并支持常见的 Unix glob 模式。
--tests-
对所有设置
test = true清单标志的目标进行基准测试。默认情况下,这包括以单元测试形式构建的库和二进制文件,以及集成测试。请注意,这也会构建所需的所有依赖项,因此库目标可能会被构建两次(一次作为单元测试,另一次作为二进制文件、集成测试等的依赖项)。可以在目标配置中设置test标志来启用或禁用特定目标。 --benchname…-
对指定的基准测试进行基准测试。此标志可多次指定,并支持常见的 Unix glob 模式。
--benches-
对所有设置了
bench = true清单标志的 target 运行基准测试。默认包括作为基准测试构建的库和二进制文件,以及 bench target。注意这也会构建所需的依赖,因此 lib target 可能会被构建两次(一次作为基准测试,一次作为二进制文件、基准测试等的依赖)。可以在清单的 target 设置中通过bench标志来启用或禁用相应 target。 --all-targets-
对所有 target 运行基准测试,等价于指定
--lib --bins --tests --benches --examples。
Feature 选择
这些 feature 标志用于控制启用哪些 feature。如果不指定任何 feature 选项,则所选的每个包都会激活 default feature。
详见feature 相关文档。
-Ffeatures--featuresfeatures-
以空格或逗号分隔的待启用 feature 列表。工作区成员的 feature 可用
package-name/feature-name语法启用。该标志可多次指定,会启用所有指定的 feature。 --all-features-
启用所选包的所有可用 feature。
--no-default-features-
不启用所选包的
defaultfeature。
编译选项
--targettriple-
针对指定的目标架构进行基准测试。该标志可以多次指定,默认为主机架构。triple 的一般格式为
<arch><sub>-<vendor>-<sys>-<abi>。可选值:
rustc --print target-list中列出的任何受支持的目标。"host-tuple",内部会替换为主机的目标。在交叉编译部分 crate、又不想把主机机器指定为目标时特别有用(例如,共享项目中可被多台主机开发的xtask)。- 自定义目标规范文件的路径。详见 Custom Target Lookup Path。
也可以通过
build.target配置项 来指定。注意,指定该标志后,Cargo 会以另一种模式运行,目标产物会被放到单独的目录中。详见构建缓存文档。
--profilename-
使用指定的 profile 进行基准测试。关于 profile 的更多细节见参考文档。
--timings-
输出每次编译耗时的信息,并跟踪一段时间内的并发情况。
构建结束后会在
target/cargo-timings目录下生成一个cargo-timing.html文件。如果你想查看之前的运行结果,还会额外生成一个文件名带时间戳的报告。这些报告仅供人工查看,不提供机器可读的计时数据。
输出选项
--target-dirdirectory-
存放所有生成产物和中间文件的目录。也可通过环境变量
CARGO_TARGET_DIR或配置项build.target-dir进行设置。默认值为工作区根目录下的target。
显示选项
默认情况下,Rust 测试框架会隐藏基准测试执行的输出,以保持结果的可读性。如果需要恢复基准测试输出(例如用于调试),可以在基准测试二进制文件中传入 --no-capture:
cargo bench -- --no-capture
-v--verbose-
使用冗长输出。指定两次可获得“非常冗长”的输出,包含依赖项警告和构建脚本输出等额外信息。也可通过配置项
term.verbose进行设置。 -q--quiet-
不打印 cargo 日志消息。也可通过配置项
term.quiet进行设置。 --colorwhen-
控制何时使用彩色输出。有效值:
auto(默认):自动检测终端是否支持颜色。always:始终显示颜色。never:从不显示颜色。
也可通过配置项
term.color进行设置。 --message-formatfmt-
诊断信息的输出格式。可以多次指定,值为逗号分隔的形式。有效取值:
human(默认):以人类可读的文本格式显示。不能与short和json同时使用。short:输出更简短的人类可读文本信息。不能与human和json同时使用。json:向 stdout 输出 JSON 信息。详见参考文档。不能与human和short同时使用。json-diagnostic-short:确保 JSON 信息的rendered字段包含 rustc 的"short"格式渲染结果。不能与human或short同时使用。json-diagnostic-rendered-ansi:确保 JSON 信息的rendered字段包含 ANSI 颜色代码,以符合 rustc 的默认配色方案。不能与human或short同时使用。json-render-diagnostics:让 Cargo 在输出的 JSON 信息中不包含 rustc 的诊断信息,而是由 Cargo 自己渲染来自 rustc 的 JSON 诊断。Cargo 自身的 JSON 信息以及来自 rustc 的其他信息仍会输出。不能与human或short同时使用。
清单选项
--manifest-pathpath-
Cargo.toml文件的路径。默认情况下,Cargo 会在当前目录及其所有上级目录中查找Cargo.toml文件。 --ignore-rust-version-
忽略包中声明的
rust-version。 --locked-
断言所使用的依赖及其版本与现有
Cargo.lock文件最初生成时完全一致。出现以下任一情况时,Cargo 将报错退出:- 锁文件缺失。
- 由于依赖解析结果不同,Cargo 试图修改锁文件。
该选项适用于需要确定性构建的环境,例如 CI 流水线。
--offline-
禁止 Cargo 以任何原因访问网络。不使用该标志时,如果 Cargo 需要访问网络但网络不可用,会直接报错停止;使用该标志后,Cargo 会尽可能在无网络的情况下继续运行。
注意,这可能导致依赖解析结果与在线模式不同。Cargo 只会使用已下载到本地的 crate,即使本地索引副本中显示有更新的版本。如果想在离线前先下载依赖,请参考 cargo-fetch(1) 命令。
也可以通过
net.offline配置项 来指定。 --frozen-
等同于同时指定
--locked和--offline。
常用选项
+toolchain-
如果 Cargo 是通过 rustup 安装的,且
cargo的第一个参数以+开头,它会被解释为 rustup 工具链名称(例如+stable或+nightly)。关于工具链覆盖的工作原理,详见 rustup 文档。 --configKEY=VALUE 或 PATH-
覆盖 Cargo 配置值。参数应为
KEY=VALUE格式的 TOML 语法,或指向额外配置文件的路径。此标志可多次指定。更多详情参见命令行覆盖章节。 -CPATH-
在执行指定操作前更改当前工作目录。这会影响 Cargo 默认查找项目清单(
Cargo.toml)的位置,以及用于发现.cargo/config.toml的搜索目录等。此选项必须出现在命令名称之前,例如cargo -C path/to/my-project build。此选项仅在nightly 通道可用, 需通过
-Z unstable-options标志启用(见 #10098)。 -h--help-
打印帮助信息。
-Zflag-
Cargo 的不稳定(仅限 nightly)标志。运行
cargo -Z help查看详情。
其他选项
--jobs 参数影响基准测试可执行文件的构建过程,但不影响运行基准测试时使用的线程数。Rust 测试框架在单线程中串行运行基准测试。
-jN--jobsN-
并行任务数。也可通过
build.jobs配置项 指定。默认值为逻辑 CPU 数量。若为负数,则将最大并行任务数设为逻辑 CPU 数量加上该值。若传入字符串default,则恢复为默认值。不能设为 0。
虽然 cargo bench 涉及编译,但它不提供 --keep-going 标志。可以使用 --no-fail-fast 在遇到第一个失败时不停止,尽可能多地运行基准测试。若想尽可能多地“编译”基准测试,可以使用 --benches 单独构建基准测试二进制文件。例如:
cargo build --benches --release --keep-going
cargo bench --no-fail-fast
ENVIRONMENT
关于 Cargo 读取的环境变量的详细信息,请参阅参考文档。
EXIT STATUS
0:Cargo 执行成功。101:Cargo 执行失败。
EXAMPLES
-
构建并运行当前包的所有基准测试:
cargo bench -
只运行指定基准测试目标中的某个特定基准测试:
cargo bench --bench bench_name -- modname::some_benchmark