bigywater.tech
Rust · 127

Debug 与 Release 构建差异

debug 和 release 的区别到底在哪?是优化,还是断言,还是溢出检查?这篇用同一个程序和 Cargo profile 的几个开关,把速度差异和行为差异分别归到各自的原因上。

33.9×
release 对 dev 的排序加速倍数
opt-level
决定速度差异的主要开关(dev 改成 3 就追平)
回绕 对 panic
250u8 + 6 在 release 与 dev 里的结果

dev 与 release 的速度

实测 · 本机执行输出
  [dev] 编译 0.74 s  二进制 615,000 字节
    debug_assertions 开启: true
    collatz 最长链 (442, 230631):167.7 ms   HashMap 50 万次更新:86.7 ms   100 万个数排序:464.7 ms   (校验 124753500 500001)
  [release] 编译 0.30 s  二进制 473,008 字节
    debug_assertions 开启: false
    collatz 最长链 (442, 230631):35.9 ms   HashMap 50 万次更新:4.1 ms   100 万个数排序:13.7 ms   (校验 124753500 500001)

迭代器链在 debug 与 release 下的差别见Iterator 链的性能;编译阶段见Rust 编译阶段。

哪个开关起作用

实测 · 本机执行输出
  dev(默认)                    collatz    166.8 ms  HashMap    84.5 ms  排序   465.2 ms  | debug_assertions 开启: true
  dev + opt-level=3          collatz     49.8 ms  HashMap     4.2 ms  排序    31.7 ms  | debug_assertions 开启: true
  release(默认)                collatz     35.8 ms  HashMap     4.1 ms  排序    14.1 ms  | debug_assertions 开启: false
  release + overflow-checks  collatz     46.7 ms  HashMap     4.0 ms  排序    14.4 ms  | debug_assertions 开启: false
  release + debug-assertions collatz     36.0 ms  HashMap     3.9 ms  排序    31.9 ms  | debug_assertions 开启: true

profile 的完整配置见Cargo Profile。

行为差异

实测 · 本机执行输出
  dev      退出码 101  stdout=''  stderr 末行=['attempt to add with overflow']
  release  退出码 0  stdout='250 + 1 * 6 = 0'  stderr 末行=[]

溢出与 panic 的更多细节见panic!、unwrap 与 expect。

分步演示

Debug 与 Release
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / rustc 1.98.1(brew)/ cargo 1.98.1;单个文件用 rustc 直接编译,需要依赖时用 cargo(经代理从 crates.io 下载);计时用 std::time::Instant,数字每次运行会有小幅抖动。每组计时是一次运行,不同次之间有几毫秒到百分之十几的波动
    • 没有验证:大型项目的编译时间差异(这里的程序编译不到 1 秒)、debuginfo 对二进制体积的影响(没有单独量)、incremental 与 codegen-units 对 release 编译时间和速度的影响、其它平台
    京ICP备2026067502号-1京公网安备11010502063487号