После обновления Rust до версии 1.38.0 с 1.36.0 я заметил, что моя программа работает медленнее - примерно на 50%.
Используя perf
, я обнаружил, что половина времени программы тратитсяв alloc::vec::Vec<T>::retain
в новой версии. В более старой версии эта функция даже не отображается. Почему retain
занимает намного больше времени в 1.38.0?
Вызов retain
выполняется следующим образом:
some_vec.retain(|&x| x < DEADLINE);
deadline
является константой u32
иsome_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);
}
С cargo +1.36.0 run --release
и затем cargo +1.38.0 run --release
.
Для этого небольшого примера я получил:
$ cargo +1.36.0 run --release
Program took: 4.624297719s
$ cargo +1.38.0 run --release
Program took: 8.293383522s