RUST_BACKTRACE=1 有多少开销?

How much overhead does RUST_BACKTRACE=1 have?

总是设置RUST_BACKTRACE=1是否合理?

它会在正常执行期间(例如在函数调用期间)引入任何(显着的?)开销,还是仅在发生恐慌时才会有开销?

我在 #rust-internals 中问过这个问题 sfackler

I believe it has no effect except during a panic

我很感兴趣,因为 Rust Playground like to have RUST_BACKTRACE enabled all the time,但目前速度差异还不够小。从 Rust 1.19.0 开始,即使对于一个不会恐慌或导致编译器错误的简单 "hello world" 程序,也有 一些 开销:

| RUST_BACKTRACE      | time (seconds) |
|---------------------|----------------|
| compile and execute |           2.48 |
| execute             |           2.02 |
| disabled            |           1.64 |
  • 编译并执行 - RUST_BACKTRACE=1 cargo run
  • 执行 - CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER='env RUST_BACKTRACE=1' cargo run
  • 禁用 - cargo run

随着时间的推移,开销并不一致;在 1.14.0 中,只需启用它 caused 10-20 seconds of delay on certain platforms!在那之前,我从未注意到任何缓慢。


在编辑方面,启用 RUST_BACKTRACE 时编译 Rust 代码的性能似乎并不是 Rust 团队目前最关心的问题。除此之外,还有许多其他有趣的事情要评估!由于这些原因,我不愿意一直戴着它。当然,如果编译器本身默认开启了这个设置,那我希望它更值得关注!

标准库中唯一读取 RUST_BACKTRACE 环境变量的地方是在函数 sys_common::backtrace::log_enabled(). That function is only called from panicking::default_hook 中,它在发生恐慌后被调用。因此,设置它应该不会影响性能,除非线程崩溃。

请注意,此标志也会影响编译器本身 (rustc)。编译器有时会发出恐慌以导致 "normal" 退出,从而抑制打印回溯但仍在计算它。当它在编译错误后退出时可能会发生这种情况。过去,人们报告说这会导致某些版本的编译器需要很长时间才能退出并设置 RUST_BACKTRACE=1

一些 crate 也可以自己处理 RUST_BACKTRACE:例如,error_chain crate 在生成错误并设置 RUST_BACKTRACE=1 时生成回溯。这会减慢使用这个箱子的项目。一个使用 error_chain 的著名项目是 cargo.