Why is `into_iter()` less efficient than `iter().clone()`?

70 points Equivalent_Peak_1496 31 comments

I am somewhat confused by the behaviour of the code here (link to playground), I always assumed that `into_iter()` should be better (more efficient) than `iter().cloned()` but that is seemingly not the case?

The 5 here is an arbitrary value initially I had 20 and was surprised that the `into_iter()` and `iter()cloned()` both do 20 clones while I would expect the `into_iter()` to only do 10 in that case.

struct Foo {
    inner: i32,
}

impl Clone for Foo {
    fn clone(&self) -> Self {
        println!("Cloned");
        Self {
            inner: self.inner.clone(),
        }
    }
}

fn main() {
    
    let nums = vec![Foo { inner: 1 }; 10];
    println!("We now have the nums vector");
    
    // The first causes 5 extra clones while the second causes 10 clones but why not 0?
    let result: Vec<_> = nums.iter().cycle().take(5).cloned().collect();
    // let result: Vec<_> = nums.into_iter().cycle().take(5).collect();
}