RUST_BACKTRACE=1会增加多少开销?

19

始终将RUST_BACKTRACE=1设置为合理吗?

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

3个回答

15
标准库中唯一读取环境变量 RUST_BACKTRACE 的位置是函数 sys_common::backtrace::log_enabled()。该函数仅从 panicking::default_hook 调用,后者会在出现 panic 后调用。因此,除非线程发生 panic,否则设置它不应对性能产生影响。
请注意,此标志还会影响编译器自身 (rustc)。当编译错误时,编译器有时会引发 panic 以进行“正常”退出,抑制打印回溯但仍计算其结果。过去,人们曾报告说这会导致某些版本的编译器设置 RUST_BACKTRACE=1 后需要长时间才能退出。
一些 crates 也可能自行处理 RUST_BACKTRACE:例如,error_chain crate 在生成错误并设置 RUST_BACKTRACE=1 时会生成回溯。这可能会减慢使用该 crate 的项目。使用 error_chain 的著名项目是 cargo

1
因此,除非线程发生恐慌,否则设置它不应该对性能产生影响。你有什么想法为什么这个声明与我的实验结果不一致? - Shepmaster
@Shepmaster 在你的测试中有太多变量:你正在测量浏览器+Web服务器+Cargo+编译+运行的时间。所有这些都可能在沙箱中运行,这可能会减慢速度。你尝试过仅测试运行可执行文件吗? - interjay
2
您说得对,我的测试包括浏览器+Web服务器,但这些在各个运行中都是常量,并且针对我本地机器而无其他情况。在Docker容器内运行也是一个常量。请注意,我并不是要说整个过程,只是使用RUST_BACKTRACE比不使用它更慢-基准。该程序是以完全相同的配置(使用 Docker)从头编译的,我唯一变化的是何时设置“RUST_BACKTRACE”变量-这是我表格中的3种情况。数据的变异性也非常低。 - Shepmaster

10

我在#rust-internals里询问了这个问题,sfackler说:

我认为除了在恐慌时没有任何影响。


那么为什么不在所有调试构建中始终开启它呢? - Jeff Walker Code Ranger
这是一个环境变量。因此设置来自外部,而不是内部。 - Steve Klabnik
7
我知道这是一个环境变量。我想问的是,为什么不将任何以调试模式编译的 Rust 可执行文件的行为设置为始终具有“RUST_BACKTRACE=1”的行为,而不考虑环境变量? - Jeff Walker Code Ranger
我不知道,这样已经持续了至少三年。 - Steve Klabnik

8

对我来说这很有意思,因为Rust Playground希望始终启用RUST_BACKTRACE,但目前速度差异不可忽略。自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中,仅启用它会导致某些平台上延迟10-20秒!在那之前,我从未注意到任何缓慢。


编辑方面,似乎启用RUST_BACKTRACE时编译的Rust代码性能目前不是Rust团队的主要关注点。除此之外还有许多其他有趣的事情需要评估!出于这些原因,我不愿意一直开启它。当然,如果编译器本身默认打开该设置,那么我会期望它更值得关注!

你的结果是在 Rust Playground 上测量的吗?(否则我不知道一个 hello world 程序为什么会花费这么长时间)。如果是这样,那么时间会根据服务器当前的繁忙程度而大幅波动,对吧? - interjay
1
@interjay,请查看该问题(展开详细信息链接)以了解测试方法。确实涉及Docker,但我的本地系统上没有其他负载。 - Shepmaster
1
我已经进行了一些测试,RUST_BACKTRACE 似乎会减慢 rustc(即使没有错误)和 cargo(即使不需要重新编译)。然而,一个简单的 hello world 程序无论是否设置该选项,运行时间都应该接近于 0。 - interjay
@interjay 很有趣 - 我意识到我在 execute 行中粘贴了错误的执行字符串。修复后的版本似乎仍然不应该触发你所指出的任何一种情况。我不确定还有什么其他原因... - Shepmaster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接