Nachdem ich Rust von 1.36.0 auf Version 1.38.0 aktualisiert hatte, stellte ich fest, dass mein Programm langsamer läuft - um etwa 50%.
Mit habe perf
ich festgestellt, dass die Hälfte der Programmzeit alloc::vec::Vec<T>::retain
in der neuen Version verbracht wird. In der älteren Version wird diese Funktion nicht einmal angezeigt. Warum retain
sollte 1.38.0 so viel länger dauern?
Der Anruf bei retain
erfolgt wie folgt:
some_vec.retain(|&x| x < DEADLINE);
deadline
ist eine Konstante u32
und some_vec
ist eine Vec<u32>
.
Ich habe das Programm ohne die retain
Aufrufe in beiden Versionen ausgeführt. In diesem Fall war 1,38,0 im Durchschnitt immer noch langsamer, jedoch nur um ~ 10% anstelle der zuvor beobachteten> 50%.
Um zusammenzufassen, was in den Tests passiert ist:
Version 1.36.0
- mit
retain
: ~ 18sec - ohne
retain
: ~ 11sec
Version 1.38.0
- mit
retain
: ~ 28sec - ohne
retain
: ~ 12sec
Für ein reproduzierbares Beispiel können Sie versuchen:
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);
}
Mit cargo +1.36.0 run --release
und dann cargo +1.38.0 run --release
.
Für dieses kleine Beispiel habe ich:
$ cargo +1.36.0 run --release
Program took: 4.624297719s
$ cargo +1.38.0 run --release
Program took: 8.293383522s
quelle
Antworten:
Im Allgemeinen ist rust.godbolt.org nützlich, um die Qualität des generierten Codes zu überprüfen (aber vergessen Sie nicht, Optimierungsflags hinzuzufügen!).
In Ihrem Fall
retain
hat sich der für generierte Code deutlich verschlechtert: https://rust.godbolt.org/z/ZhVCDgSie sollten dies also Rust als Leistungsregression melden .
quelle