在更新到Rust 1.38.0后,为什么Vec :: retain运行速度较慢?

Mig*_*uel 8 performance rust

将Rust从1.36.0更新到1.38.0后,我注意到我的程序运行速度较慢–降低了约50%。

使用perf,我发现alloc::vec::Vec<T>::retain新版本花费了一半的程序时间。在旧版本中,此功能甚至不会显示。为什么retain在1.38.0中需要花费更长的时间?

呼叫retain是这样完成的:

some_vec.retain(|&x| x < DEADLINE);
Run Code Online (Sandbox Code Playgroud)

deadline是一个常数u32some_vec是一个Vec<u32>

retain在两个版本中都没有调用的情况下运行了该程序。在这种情况下,平均1.38.0仍然较慢,但仅降低了〜10%,而不是之前看到的> 50%。

回顾一下测试中发生的情况:

版本1.36.0

  • retain:〜18秒
  • 没有retain:〜11秒

版本1.38.0

  • retain:〜28秒
  • 没有retain:〜12秒

对于可重现的示例,您可以尝试:

use std::time::Instant;

fn main() {
    let start = Instant::now();
    let mut my_vec: Vec<u32>;
    for _ in 0..100_000 {
        my_vec = (0..10_000).collect();
        my_vec.retain(|&x| x < 9000);
        my_vec.retain(|&x| x < 8000);
        my_vec.retain(|&x| x < 7000);
        my_vec.retain(|&x| x < 6000);
        my_vec.retain(|&x| x < 5000);
        my_vec.retain(|&x| (x < 5) & (x > 2));
    }
    let duration = start.elapsed();
    println!("Program took: {:?}", duration);
}
Run Code Online (Sandbox Code Playgroud)

cargo +1.36.0 run --release然后cargo +1.38.0 run --release

对于这个小例子,我得到了:

some_vec.retain(|&x| x < DEADLINE);
Run Code Online (Sandbox Code Playgroud)

Kor*_*nel 2

一般来说,rust.godbolt.org对于检查生成代码的质量很有用(但不要忘记添加优化标志!)

在您的情况下,生成的代码retain显然已经变得更糟: https: //rust.godbolt.org/z/ZhVCDg

因此,您应该将其作为性能回归报告给 Rust 。

  • 对于好奇的人:https://github.com/rust-lang/rust/issues/65970 (4认同)