In Rust, an assert can turn multiple bounds checks on array indexing into just a single bounds check. Maybe it's something along those lines here too.
pub fn no_assert(input: &mut [u8]) {
for i in 0..10 {
input[i] += input[i+1];
}
}
pub fn with_assert(input: &mut [u8]) {
assert!(input.len() >= 11);
for i in 0..10 {
input[i] += input[i+1];
}
}
The no_assert function ends up doing a bounds check for every iteration, and the with_assert function only does a single check.However, I believe a future Rust RFC could turn that around and validate the idea that in some cases such things could change execution order, even if it has noticeable side effects.
(No idea if it's technically feasible!)
Both loops get entirely unrolled. Its 5 instructions for each iteration in the first example, and only 3 in the second example. (To say nothing of the fact that conditional jumps are (usually?) much more expensive than add/mov instructions)