# For loops : faster iterations, cleaner code

Hi,

I've been messing around with for loops in my code. Basically, I often have begin and end coordinates from multiple arrays that I need to move around. Example:

``````let a : Vec<u8> = ....
let b : Vec<u8> = ....
let c : Vec<u8> = ....
let d : Vec<u8> = ....

// and then I need to copy segment a[x..y] -> c[i..j]
// and so on
``````

What I use are for loops and then copy character by character. I figured It is the fastest way:

``````use std::time::Instant;

fn main() {
let ext = |v: &mut Vec<u8>, ev: &Vec<u8>, b: usize| -> usize {
let mut x = b;
for i in ev.iter() {
v[x] = *i;
x += 1;
}
x
};
{
let before = Instant::now();

let mut a = vec![0u8; 2000000000];
for i in 0..a.len() {
a[i] = 9u8;
}

println!("Elapsed time  a): {:.2?}", before.elapsed());
}

{
let before = Instant::now();
let a = vec![9u8; 10];
let mut b = Vec::new();
for i in 0..200000000 {
b.extend(a.clone());
}
println!("Elapsed time b): {:.2?}", before.elapsed());
}

{
let before = Instant::now();
let a = vec![9u8; 10];
let mut b = vec![0u8; 2000000000];
let mut y = 0;
for i in 0..200000000 {
y = ext(&mut b, &a, y);
}
println!("Elapsed time c): {:.2?}", before.elapsed());
}

{
let before = Instant::now();
let mut b = Vec::with_capacity(2000000000);
for i in 0..2000000000 {
b.push(9u8);
}
println!("Elapsed time d): {:.2?}", before.elapsed());
}
}

``````

Runtimes:

``````Elapsed time a): 949.04ms
Elapsed time b): 6.08s
Elapsed time c): 1.52s
Elapsed time d): 4.81s
``````

But having these for loops looks nasty... What I consider clean, is the extend method but it's 6x slower and has 30-40% larger memory footprint than "a)" is there some other way to extend a vector without directly copy/pasting characters as in case of for loops?

In `b)` you are cloning the `a` vector on every iteration. Don't do that

``````let before = Instant::now();
let a = vec![9u8; 10];
let mut b: Vec<u8> = Vec::new();
for i in 0..200000000 {
b.extend(&a);
}
println!("Elapsed time b): {:.2?}", before.elapsed());
``````

You may also like this:

``````let before = Instant::now();
let mut b = Vec::with_capacity(2000000000);
b.extend((0..2000000000).map(|_| 9u8));
println!("Elapsed time e): {:.2?}", before.elapsed());
``````

Anyway this kinda sounds like an XY problem. Is filling a vector with all nines the problem you are trying to solve? You can do that with `vec![9u8; 2000000000]`.

1 Like

well i am trying to copy a slice from one vec to another starting at x and ends at y... so yes, it nos just a simple copy ... sorry but i did not know about e)

I recommend the `copy_from_slice` method. Note that you can call it like this:

``````(&mut vec[a..b]).copy_from_slice(&vec2[x..y]);
``````
3 Likes

For special needs there is also the drain() method that takes out a slice from the and rearranges the original vector. It is not exactly what you are asking, but is good to know.

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.