Open
Description
While solving AoC Day 4 I ran into the following performance difference:
fn main() {
let input = vec![
(2, 4, 6, 8),
(2, 3, 4, 5),
(5, 7, 7, 9),
(2, 8, 3, 7),
(6, 6, 4, 6),
(2, 6, 4, 8), // .. 500000000 lines of random data, read from disk with real code (~12GB)
];
// 1761ms on my machine
let _variant_a_result = variant_a(&input);
// 656ms on my machine
let _variant_b_result = variant_b(&input);
}
pub fn variant_a(input: &[(usize, usize, usize, usize)]) -> usize {
input
.iter()
.filter(|(a, b, c, d)| a <= c && d <= b || c <= a && b <= d)
.count()
}
pub fn variant_b(input: &[(usize, usize, usize, usize)]) -> usize {
input
.iter()
.filter(|&&(a, b, c, d)| a <= c && d <= b || c <= a && b <= d)
.count()
}
As you can see, using |&&(a, b, c, d)|
on the same closure is 2.6 times faster than |(a, b, c, d)|
.
Viewing the compiled code makes this clear: https://rust.godbolt.org/z/oaeaGGPK7
Is this a compiler behavior a developer should know / expect?
Meta
Thanks to @Arnavion for pointing this out.
rustc --version --verbose
:
rustc 1.67.0-nightly (c090c6880 2022-12-01)