Iter is (slightly) faster than loop('for', 'while' and 'loop'), I learned that from many documentations, but none explains why.
A naive test code like this could tell iter is a little bit faster:
use std::time::Instant;
const VEC_SIZE: usize = 10000000;
fn use_iter(vec: &mut Vec<usize>) {
vec.iter_mut().enumerate().for_each(|(i, v)| *v = i);
}
fn use_for(vec: &mut Vec<usize>) {
for i in 0..vec.len() {
vec[i] = i;
}
}
fn use_while(vec: &mut Vec<usize>) {
let mut i = 0;
let len = vec.len();
while i < len {
vec[i] = i;
i += 1;
}
}
fn main() {
let mut vec = vec![0; VEC_SIZE];
// Warm up a little
for _ in 0.. 10 {
use_while(&mut vec);
}
let now = Instant::now();
for _ in 0.. 10 {
use_iter(&mut vec);
}
let elapsed = now.elapsed();
println!("time elapsed using iter: {:?}", elapsed);
let now = Instant::now();
for _ in 0.. 10 {
use_for(&mut vec);
}
let elapsed = now.elapsed();
println!("time elapsed using for: {:?}", elapsed);
let now = Instant::now();
for _ in 0.. 10 {
use_while(&mut vec);
}
let elapsed = now.elapsed();
println!("time elapsed using while: {:?}", elapsed);
}
But what I am courious about is why iter is faster, they all have to visit same memory address and perform same operation. And loop is so direct, yet iter might even need to run more code (I don't know if this is true in CPU instruction level, so I say might.), because we need to make a iteration struct out of it and call next()
to iterate, how could it be faster?
I noticed that the assembly code generated by rustc is different using iter and loop, but it's way to complicated for me to understand.
Here is some of my guesses:
- compiler optimization (but based on what ? Why loop cannot be optimized?)
- no boundry check ?
- something ralated mutability or memory access?
I hope someone had studied this and got an answer to share.