入门 The Cargo Team 2026-09-13 15:48:22 · 0 阅读

第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 本身。

-p spec
--package spec

只对指定的包进行基准测试。SPEC 格式参见 cargo-pkgid(1)。此标志可多次指定,并支持 *?[] 等常见的 Unix glob 模式。但为了避免 shell 在 Cargo 处理之前误展开这些模式,每个模式都必须用单引号或双引号包起来。

--workspace

对 workspace 中的所有成员进行基准测试。

--all

--workspace 的弃用别名。

--exclude SPEC

排除指定的包,必须与 --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> 环境变量,以便通过 envvar 函数来定位可执行文件。

传入目标选择标志时,只会对指定的目标进行基准测试。

注意 --bin--example--test--bench 标志也支持 *?[] 等常见的 Unix glob 模式。但为了避免 shell 在 Cargo 处理之前就展开 glob 模式,必须用单引号或双引号把每个 glob 模式包起来。

--lib

对包的库进行基准测试。

--bin name

对指定的二进制目标进行基准测试。该标志可以多次指定,并支持常见的 Unix glob 模式。

--bins

对所有二进制目标进行基准测试。

--example name

对指定的示例进行基准测试。此标志可多次指定,并支持常见的 Unix glob 模式。

--examples

对所有示例目标进行基准测试。

--test name

对指定的集成测试进行基准测试。此标志可多次指定,并支持常见的 Unix glob 模式。

--tests

对所有设置 test = true 清单标志的目标进行基准测试。默认情况下,这包括以单元测试形式构建的库和二进制文件,以及集成测试。请注意,这也会构建所需的所有依赖项,因此库目标可能会被构建两次(一次作为单元测试,另一次作为二进制文件、集成测试等的依赖项)。可以在目标配置中设置 test 标志来启用或禁用特定目标。

--bench name

对指定的基准测试进行基准测试。此标志可多次指定,并支持常见的 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 相关文档

-F features
--features features

以空格或逗号分隔的待启用 feature 列表。工作区成员的 feature 可用 package-name/feature-name 语法启用。该标志可多次指定,会启用所有指定的 feature。

--all-features

启用所选包的所有可用 feature。

--no-default-features

不启用所选包的 default feature。

编译选项

--target triple

针对指定的目标架构进行基准测试。该标志可以多次指定,默认为主机架构。triple 的一般格式为 <arch><sub>-<vendor>-<sys>-<abi>

可选值:

  • rustc --print target-list 中列出的任何受支持的目标。
  • "host-tuple",内部会替换为主机的目标。在交叉编译部分 crate、又不想把主机机器指定为目标时特别有用(例如,共享项目中可被多台主机开发的 xtask)。
  • 自定义目标规范文件的路径。详见 Custom Target Lookup Path

也可以通过 build.target 配置项 来指定。

注意,指定该标志后,Cargo 会以另一种模式运行,目标产物会被放到单独的目录中。详见构建缓存文档。

--profile name

使用指定的 profile 进行基准测试。关于 profile 的更多细节见参考文档

--timings

输出每次编译耗时的信息,并跟踪一段时间内的并发情况。

构建结束后会在 target/cargo-timings 目录下生成一个 cargo-timing.html 文件。如果你想查看之前的运行结果,还会额外生成一个文件名带时间戳的报告。这些报告仅供人工查看,不提供机器可读的计时数据。

输出选项

--target-dir directory

存放所有生成产物和中间文件的目录。也可通过环境变量 CARGO_TARGET_DIR 或配置项 build.target-dir 进行设置。默认值为工作区根目录下的 target

显示选项

默认情况下,Rust 测试框架会隐藏基准测试执行的输出,以保持结果的可读性。如果需要恢复基准测试输出(例如用于调试),可以在基准测试二进制文件中传入 --no-capture

cargo bench -- --no-capture
-v
--verbose

使用冗长输出。指定两次可获得“非常冗长”的输出,包含依赖项警告和构建脚本输出等额外信息。也可通过配置项 term.verbose 进行设置。

-q
--quiet

不打印 cargo 日志消息。也可通过配置项 term.quiet 进行设置。

--color when

控制何时使用彩色输出。有效值:

  • auto(默认):自动检测终端是否支持颜色。
  • always:始终显示颜色。
  • never:从不显示颜色。

也可通过配置项 term.color 进行设置。

--message-format fmt

诊断信息的输出格式。可以多次指定,值为逗号分隔的形式。有效取值:

  • human(默认):以人类可读的文本格式显示。不能与 shortjson 同时使用。
  • short:输出更简短的人类可读文本信息。不能与 humanjson 同时使用。
  • json:向 stdout 输出 JSON 信息。详见参考文档。不能与 humanshort 同时使用。
  • json-diagnostic-short:确保 JSON 信息的 rendered 字段包含 rustc 的"short"格式渲染结果。不能与 humanshort 同时使用。
  • json-diagnostic-rendered-ansi:确保 JSON 信息的 rendered 字段包含 ANSI 颜色代码,以符合 rustc 的默认配色方案。不能与 humanshort 同时使用。
  • json-render-diagnostics:让 Cargo 在输出的 JSON 信息中不包含 rustc 的诊断信息,而是由 Cargo 自己渲染来自 rustc 的 JSON 诊断。Cargo 自身的 JSON 信息以及来自 rustc 的其他信息仍会输出。不能与 humanshort 同时使用。

清单选项

--manifest-path path

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 文档

--config KEY=VALUEPATH

覆盖 Cargo 配置值。参数应为 KEY=VALUE 格式的 TOML 语法,或指向额外配置文件的路径。此标志可多次指定。更多详情参见命令行覆盖章节

-C PATH

在执行指定操作前更改当前工作目录。这会影响 Cargo 默认查找项目清单(Cargo.toml)的位置,以及用于发现 .cargo/config.toml 的搜索目录等。此选项必须出现在命令名称之前,例如 cargo -C path/to/my-project build

此选项仅在nightly 通道可用, 需通过 -Z unstable-options 标志启用(见 #10098)。

-h
--help

打印帮助信息。

-Z flag

Cargo 的不稳定(仅限 nightly)标志。运行 cargo -Z help 查看详情。

其他选项

--jobs 参数影响基准测试可执行文件的构建过程,但不影响运行基准测试时使用的线程数。Rust 测试框架在单线程中串行运行基准测试。

-j N
--jobs N

并行任务数。也可通过 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

  1. 构建并运行当前包的所有基准测试:

    cargo bench
    
  2. 只运行指定基准测试目标中的某个特定基准测试:

    cargo bench --bench bench_name -- modname::some_benchmark
    

SEE ALSO

cargo(1), cargo-test(1)

评论 (0)