I noticed that by switching from rustc 1.77.0 to 1.78.0, some code I have apparently runs significantly slower (full optimised build) than before.
The code is in git@github.com:tallinn1960/rain_collected.git. It has a criterion benchmark, which shows that the function compute_rain_collected runs significantly slower when compiled by 1.78.0, a 176% regression.
compute_rain_collected_trap/compute_rain_collected
time: [23.291 ms 23.338 ms 23.386 ms]
change: [+175.17% +176.07% +176.89%] (p = 0.00 < 0.05)
Performance has regressed.
Is this a criterion flaw or is it a compiler regression? All other tested functions in that benchmark perform the same with both compiler versions though.
For aarch64, the 1.78 version has fewer branches which should be beneficial but might be worse if the branch predictor does a good job for the use case.
The order changes a lot depending on how many iterations occur.
This made 1.77, 1.78, and nightly about the same as previous beta, and beta now takes the same as previous nightly/1.78. In my experience copied sucks, but I'm always hopeful it'll be fixed someday.
I'm gonna turn this into a procedural loop next and see how that goes.
Edit: while loop is worse, but when the iterator is copied it's fast in everything except nightly!
pub fn compute_rain_collected(height: &[i64]) -> u64 {
let mut height = height.iter().copied();
let mut state = (height.next(), height.next_back());
let mut acc = (i64::MIN, 0u64);
while let (Some(left), Some(right)) = state {
let x = if left <= right {
state = (height.next(), Some(right));
left
} else {
state = (Some(left), height.next_back());
right
};
let stepsize = x.max(acc.0);
acc = (stepsize, acc.1 + (stepsize - x) as u64);
}
acc.1
}
There's some interesting pointer provenance questions about slice iterators that are coming up now that LLVM is starting to try to actually fix a bunch of long-time bugs around it.