The previous version of UniformInt allowed the compiler to remove bounds checks. It can't do the same for our new widening multiply method.
You can verify with RUSTFLAGS='--emit=asm' cargo build --release:
extern crate rand;
use rand::{XorShiftRng, Rng};
pub fn foo(rng: &mut XorShiftRng) -> usize {
let arr = [1; 77];
// `rand = "0.4"`, no bounds checking
// `rand = "0.5"`, bounds checking
arr[rng.gen_range(0, arr.len())]
}
Is there something we could do to fix this? A change in UniformInt? Some sort of compiler hint? Or would this require a smarter compiler?
If we can't fix it, perhaps we should document this behavior. We should consider ways to mitigate the problem, such as using unchecked indexing in library code like shuffle, choose, etc.
The previous version of
UniformIntallowed the compiler to remove bounds checks. It can't do the same for our new widening multiply method.You can verify with
RUSTFLAGS='--emit=asm' cargo build --release:Is there something we could do to fix this? A change in
UniformInt? Some sort of compiler hint? Or would this require a smarter compiler?If we can't fix it, perhaps we should document this behavior. We should consider ways to mitigate the problem, such as using unchecked indexing in library code like
shuffle,choose, etc.