After updating Rust to version 1.38.0 from 1.36.0, I noticed that my program runs slower — by about 50%.
Using perf, I discovered that half of the program time is spent in alloc::vec::Vec<T>::retain in the new version. In the older version, this function does not even show up. Why would retain take so much longer in 1.38.0?
The call to retain is done like this:
some_vec.retain(|&x| x < DEADLINE);
deadline is a constant u32 and some_vec is a Vec<u32>.
I ran the program without the retain calls in both versions. In this case, 1.38.0 was still slower on average, but only by ~10% instead of the > 50% seen before.
To recap what happened in the tests:
Version 1.36.0
- with
retain: ~18sec - without
retain: ~11sec
Version 1.38.0
- with
retain: ~28sec - without
retain: ~12sec
For a reproducible example, you can try:
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);
}
With cargo +1.36.0 run --release and then cargo +1.38.0 run --release.
For this small example, I got:
$ cargo +1.36.0 run --release
Program took: 4.624297719s
$ cargo +1.38.0 run --release
Program took: 8.293383522s