https://gist.github.com/lsk569937453/b42a8cfce21bd20c5da8737db1f5a1b1
加了 anyhow = { version = "1.0.xx"}之后,gateway 的 TPS 从 8w 降到 4w(4 核 8G 的 docker 容器)。
anyhow = { version = "1.0.xx", default-features = false }
目前不确定是 anyhow 的问题还是 hyper v1 的问题。我用同样的代码在 hyper v0.14.xx 实现了一遍,没有发现问题。所以倾向是 hyper v1 的问题。
1
PTLin 232 天前
虽然不知道你代码具体原因是什么,但是 anyhow 1.0.80 不同 feature backtrack 的速度确实不一样,不开启 std feature 的话用的是 anyhow 自己的实现,开启的话用的是标准库的实现,在 Windows 上好像是标准库的实现比较慢。
```rust use anyhow::anyhow; use std::time::Instant; fn main() { for _ in 0..20 { let now = Instant::now(); for _ in 0..10000 { let _ = anyhow!("asd"); } println!("{:?}", now.elapsed()); } } ``` |
2
lsk569937453 OP 应该和 anyhow 的版本没什么关系,我换成 anyhow = { version = "1.0.70"}还是有同样的问题。
|
3
PTLin 232 天前
|
4
lsk569937453 OP 保险起见,不用 anyhow 这个 crate 了,代码改动还小点。
|
5
PTLin 230 天前
@lsk569937453 我比较好奇题主是什么平台运行的代码
|
6
lsk569937453 OP |
7
Hantong 153 天前
测试环境:
rustc 1.78.0 (9b00956e5 2024-04-29), PTLin 给出的代码 Linux 平台仍然观察到了明显性能折损, profile.release 下, 使用 =1.0.86 版本的 anyhow 比 =1.0.76 版本的 anyhow 慢了 2 倍有余(default-feature = true 下)... 相当恐怖... btw, 个人有个 gRPC server 的项目, 观察到 prost 间接依赖了 anyhow, 只能说但凡涉及 gRPC 的几乎全都会受影响, 毕竟 prost 的影响力蛮大的... bbtw, 得 anyhow = { version = "=1.0.70" } 这样才能强制指定版本. |
8
Hantong 153 天前
对于此问题, 修复方法推荐强制指定 anyhow 版本到 =1.0.76
|
9
RTSmile 145 天前 via iPhone
@Hantong 这个问题 anyhow 的 issue 里面已经有人讨论了,Rust 语言的开发者也有回应说升级到 nightly 版本可能会有性能提升。不过目前的讨论都是仅限于 Windows 版本的,似乎他们并没有注意到 Linux 的性能问题?
|
10
RTSmile 145 天前 via iPhone
@Hantong anyhow 那边说是 Rust 默认启用了 std 的 backtrace 导致的问题。
我建议如果你有简单的例子能说明 Linux 上有明显的性能下降的话最好提一下,好像 anyhow 至今对解决这个问题都无动于衷:( |
11
RTSmile 145 天前 via iPhone
anyhow 的 issue 里面有人反馈设置 RUST_LIB_BACKTRACE=0 可以解决这个问题。看起来是 rust 标准库里面的 backtrace 导致的问题。
|
12
Hantong 119 天前
@RTSmile 毕竟是 std 的问题, 修复蛮麻烦的.
benchmark 一下就能看出来, 我原来还不信的. 最简单的复现代码, 虽然不够严谨. 严谨点得用 benchmark, 或者上火焰图看看什么情况, 我对为什么慢不感兴趣所以没弄. ```rust fn main() { let mut result = Vec::with_capacity(20); for _ in 0..20 { let now = Instant::now(); for _ in 0..10000 { let _ = anyhow::anyhow!("test error"); } result.push(now.elapsed().as_nanos()); } let avg = result.iter().sum::<u128>() as f64 / 20f64 / 1000f64; println!("avg cost: {}s", avg); } ``` 反正我现在是遵照一位大佬的建议锁 1.0.76 这最后一个正常的版本, 然后所有依赖 anyhow 的库也基本会对齐依赖版本. 还在观察中, 后天有空看看 nightly 版本下的情况. |