V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lsk569937453
V2EX  ›  Rust

hyper v1+anyhow 可能导致性能急速下降

  •  
  •   lsk569937453 · 294 天前 · 1746 次点击
    这是一个创建于 294 天前的主题,其中的信息可能已经有所发展或是发生改变。

    出问题的源码

    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 }

    怎么避免

    • 项目依赖的 crates 中的 anyhow 必须是非 std 的即 anyhow = { version = "1.0.xx", default-features = false }
    • 项目依赖的 crates 中,如果依赖了 anyhow ,也必须是非 std 得。否则,项目会出现性能下降。比如项目依赖了 log4rs 和 https://github.com/BinChengZhao/delay-timer,由于这两个 crates 依赖了 std 的 anyhow ,因此需要将 log4rs 和 delay-timer 排除掉,否则也会出问题。

    问题原因

    目前不确定是 anyhow 的问题还是 hyper v1 的问题。我用同样的代码在 hyper v0.14.xx 实现了一遍,没有发现问题。所以倾向是 hyper v1 的问题。

    13 条回复    2024-10-21 14:20:49 +08:00
    PTLin
        1
    PTLin  
       294 天前
    虽然不知道你代码具体原因是什么,但是 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());
    }
    }
    ```
    lsk569937453
        2
    lsk569937453  
    OP
       294 天前
    应该和 anyhow 的版本没什么关系,我换成 anyhow = { version = "1.0.70"}还是有同样的问题。
    PTLin
        3
    PTLin  
       294 天前
    又测试了下,调用层数多点能有十多倍的差距
    https://imgur.com/SVIrrfT
    https://imgur.com/2LDykii
    lsk569937453
        4
    lsk569937453  
    OP
       292 天前
    保险起见,不用 anyhow 这个 crate 了,代码改动还小点。
    PTLin
        5
    PTLin  
       292 天前
    @lsk569937453 我比较好奇题主是什么平台运行的代码
    lsk569937453
        6
    lsk569937453  
    OP
       291 天前
    Hantong
        7
    Hantong  
       215 天前
    测试环境:
    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" } 这样才能强制指定版本.
    Hantong
        8
    Hantong  
       215 天前
    对于此问题, 修复方法推荐强制指定 anyhow 版本到 =1.0.76
    RTSmile
        9
    RTSmile  
       207 天前 via iPhone
    @Hantong 这个问题 anyhow 的 issue 里面已经有人讨论了,Rust 语言的开发者也有回应说升级到 nightly 版本可能会有性能提升。不过目前的讨论都是仅限于 Windows 版本的,似乎他们并没有注意到 Linux 的性能问题?
    RTSmile
        10
    RTSmile  
       207 天前 via iPhone
    @Hantong anyhow 那边说是 Rust 默认启用了 std 的 backtrace 导致的问题。
    我建议如果你有简单的例子能说明 Linux 上有明显的性能下降的话最好提一下,好像 anyhow 至今对解决这个问题都无动于衷:(
    RTSmile
        11
    RTSmile  
       207 天前 via iPhone
    anyhow 的 issue 里面有人反馈设置 RUST_LIB_BACKTRACE=0 可以解决这个问题。看起来是 rust 标准库里面的 backtrace 导致的问题。
    Hantong
        12
    Hantong  
       181 天前
    @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 版本下的情况.
    Hantong
        13
    Hantong  
       60 天前
    目前根据 bench 结果:

    ```
    Gnuplot not found, using plotters backend
    Anyhow/anyhow/v1.0.76 time: [46.255 ns 50.158 ns 54.338 ns]
    change: [-3.3466% +7.6940% +20.010%] (p = 0.18 > 0.05)
    No change in performance detected.
    Found 5 outliers among 100 measurements (5.00%)
    3 (3.00%) high mild
    2 (2.00%) high severe
    Anyhow/anyhow/v1.0.90 time: [48.072 ns 56.167 ns 63.721 ns]
    change: [-29.746% +34.093% +175.67%] (p = 0.69 > 0.05)
    No change in performance detected.
    Found 16 outliers among 100 measurements (16.00%)
    11 (11.00%) high mild
    5 (5.00%) high severe
    ```

    但是我的测试环境发生变动: AMD AI9 HX370, 7500MT LPDDR5.

    ```
    rustc 1.84.0-nightly (e7c0d2750 2024-10-15)
    binary: rustc
    commit-hash: e7c0d2750726c1f08b1de6956248ec78c4a97af6
    commit-date: 2024-10-15
    host: x86_64-pc-windows-msvc
    release: 1.84.0-nightly
    LLVM version: 19.1.1
    ```

    测试代码:

    ```rust
    use criterion::{criterion_group, criterion_main, BatchSize, Criterion};

    fn bench_maps(c: &mut Criterion) {
    let mut group = c.benchmark_group("Anyhow");

    group.bench_function("anyhow/v1.0.76", |b| {
    b.iter_batched(
    || anyhow_1_0_76::anyhow!("test error"),
    |e| {
    criterion::black_box({
    let _ = e;
    });
    },
    BatchSize::SmallInput,
    )
    });

    group.bench_function("anyhow/v1.0.90", |b| {
    b.iter_batched(
    || anyhow_1_0_90::anyhow!("test error"),
    |e| {
    criterion::black_box({
    let _ = e;
    });
    },
    BatchSize::SmallInput,
    )
    });
    }

    criterion_group!(benches, bench_maps);
    criterion_main!(benches);
    ```

    切换至当前 stable rust 测试:

    ```
    rustc 1.81.0 (eeb90cda1 2024-09-04)
    binary: rustc
    commit-hash: eeb90cda1969383f56a2637cbd3037bdf598841c
    commit-date: 2024-09-04
    host: x86_64-pc-windows-msvc
    release: 1.81.0
    LLVM version: 18.1.7
    ```

    ```
    Running benches/anyhow.rs (target\release\deps\anyhow-e035dda9f6eff98f.exe)
    Gnuplot not found, using plotters backend
    Anyhow/anyhow/v1.0.76 time: [7.3229 ns 7.5644 ns 7.9092 ns]
    change: [-5.8063% -1.9072% +1.6252%] (p = 0.33 > 0.05)
    No change in performance detected.
    Found 7 outliers among 100 measurements (7.00%)
    3 (3.00%) high mild
    4 (4.00%) high severe
    Anyhow/anyhow/v1.0.90 time: [46.830 ns 53.064 ns 59.741 ns]
    change: [-16.795% -3.3065% +13.223%] (p = 0.68 > 0.05)
    No change in performance detected.
    Found 6 outliers among 100 measurements (6.00%)
    3 (3.00%) high mild
    3 (3.00%) high severe
    ```

    emmm, 奇怪的结果.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2718 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 05:38 · PVG 13:38 · LAX 21:38 · JFK 00:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.