In Rust we often act upon slices—even vectors or strings can be used as slices. Suppose we want to append to one slice with the elements in another.
With a for
-loop, we can add elements individually from one slice. But this is inefficient. The extend_from_slice
function can add all the elements faster.
Consider this simple Rust example. We have a string
and we want to append the bytes from the string
to a byte
vector (u8
).
as_bytes()
on the string
to get the bytes—the string
cannot be acted upon directly.for
-loop for this.for
-loop can. We can benchmark this.fn main() { // Append bytes from a string to a slice. let mut buffer = vec![]; let data = "bird"; buffer.extend_from_slice(data.as_bytes()); // Print length. println!("BUFFER LENGTH = {}", buffer.len()); }BUFFER LENGTH = 4
How does extend from slice compare to a for
-loop with push()
? We can time this. Consider this benchmark—it adds a byte
vector to a target byte
vector in 2 ways.
extend_from_slice
to add one byte
vector to a target vector repeatedly. The vector's capacity is set to avoid allocations.for
-loop and push()
to copy one vector to another many times. A loop is used instead of extend_from_slice
.for
-loop. In testing, this seems to be true for vectors of any length.use std::time::*; fn main() { let iterations = 1000000; // The data we are appending to the slice. let mut data: Vec<u8> = vec![]; for i in 0..20 { data.push(i); } // Version 1: Use extend_from_slice. let now = Instant::now(); let mut target = Vec::with_capacity(iterations * data.len()); for i in 0..iterations { target.extend_from_slice(&data); } println!("{} ms", now.elapsed().as_millis()); // Version 2: Use for-loop with push. let now = Instant::now(); let mut target = Vec::with_capacity(iterations * data.len()); for i in 0..iterations { for x in &data { target.push(x); } } println!("{} ms", now.elapsed().as_millis()); }18 ms extend_from_slice 82 ms for, push
We reviewed 2 ways to add one vector's elements to another vector. The extend_from_slice
function has better performance than a for
-loop, and simpler syntax.