bigywater.tech
Rust · 123

Rust 编译阶段

Rust 编译到底分几步?每一步产出什么?时间花在哪里?这篇不画示意图,而是让 rustc 自己报告:各 --emit 产物、time-passes 的全部计时条目,以及 debug 与 release 的对比。

43 个
time-passes 报告的计时条目数(嵌套的)
37×
LLVM IR 文本体积对 MIR 文本体积的倍数
3.4×
release 的 LLVM_passes 耗时对 debug 的倍数

编译会产出哪些东西

实测 · 本机执行输出
  --emit=dep-info  → .d           395 字节
  --emit=metadata  → .rmeta     4,650 字节
  --emit=mir       → .mir      10,174 字节
  --emit=llvm-ir   → .ll      380,024 字节
  --emit=asm       → .s       232,246 字节
  --emit=obj       → .o        86,040 字节

MIR 见MIR 是什么;LLVM IR 见LLVM IR 与优化。

各阶段耗时

实测 · 本机执行输出
  共 43 个计时条目;耗时最长的 12 个(秒):
      0.114 s  total
      0.055 s  link_binary
      0.055 s  link_crate
      0.055 s  link
      0.047 s  run_linker
      0.023 s  LLVM_passes
      0.022 s  finish_ongoing_codegen
      0.016 s  codegen_crate
      0.010 s  monomorphization_collector_graph_walk
      0.007 s  type_check_crate
      0.006 s  get_apple_sdk_root
      0.004 s  coherence_checking
   ['time:   0.114; rss:   24MB ->   74MB (  +50MB)\ttotal']

time-passes 使用 RUSTC_BOOTSTRAP=1;只测了一个 20 行的小程序,大型 crate 的耗时分布(类型检查、借用检查占比更大)没有测。

流水线的顺序

实测 · 本机执行输出
    0.000  parse_crate
    0.000  crate_injection
    0.003  expand_crate
    0.003  macro_expand_crate
    0.000  maybe_building_test_harness
    0.000  AST_validation
    0.000  finalize_imports
    0.000  compute_effective_visibilities
    0.000  lint_reexports
    0.000  finalize_macro_resolutions
    0.001  late_resolve_crate
    0.000  resolve_postprocess
    0.001  resolve_crate
    0.000  write_dep_info
    0.000  complete_gated_feature_checking
    0.000  looking_for_entry_point
    0.000  check_externally_implementable_items
    0.000  looking_for_derive_registrar
    0.000  unused_lib_feature_checking
    0.000  misc_checking_1
    0.004  coherence_checking
    0.007  type_check_crate
    0.003  MIR_borrow_checking
    0.000  module_lints
    0.000  lint_checking
    0.000  privacy_checking_modules
    0.001  misc_checking_3
    0.000  monomorphization_collector_root_collections
    0.010  monomorphization_collector_graph_walk
    0.001  partition_and_assert_distinct_symbols
    0.000  write_allocator_module
    0.004  codegen_to_LLVM_IR
    0.016  codegen_crate
    0.000  serialize_dep_graph
    0.023  LLVM_passes
    0.000  join_worker_thread
    0.022  finish_ongoing_codegen
    0.006  get_apple_sdk_root
    0.047  run_linker
    0.055  link_binary
    0.055  link_crate
    0.055  link
    0.114  total

debug 与 release

实测 · 本机执行输出
  debug(opt-level=0)   total 0.106 s   LLVM_passes 0.020 s   type_check_crate 0.006 s   link_binary 0.049 s
  release(-O)          total 0.191 s   LLVM_passes 0.068 s   type_check_crate 0.005 s   link_binary 0.045 s

更多构建差异见Debug 与 Release 构建差异。

分步演示

编译阶段
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / rustc 1.98.1(brew)/ cargo 1.98.1;单个文件用 rustc 直接编译,需要依赖时用 cargo(经代理从 crates.io 下载);计时用 std::time::Instant,数字每次运行会有小幅抖动。time-passes 为 -Z 选项,需要 RUSTC_BOOTSTRAP=1
    • 没有验证:大型 crate(如 tokio)的阶段耗时分布、增量编译对各阶段的影响、并行前端(-Z threads)、链接器替换(lld / mold)的耗时变化、cargo --timings 的输出
    京ICP备2026067502号-1京公网安备11010502063487号