Extend from slice. 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.
Example. Consider this simple Rust example. We have a string and we want to append the bytes from the string to a byte vector (u8).
Detail We must call as_bytes() on the string to get the bytes—the string cannot be acted upon directly.
Next We call extend from slice to copy the bytes into the target buffer. We do not use a for-loop for this.
Important The extend from slice function can copy the bytes faster than a 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
Benchmark. 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.
Version 1 We call extend_from_slice to add one byte vector to a target vector repeatedly. The vector's capacity is set to avoid allocations.
Version 2 We use an inner for-loop and push() to copy one vector to another many times. A loop is used instead of extend_from_slice.
Result It is much faster to use extend from slice instead of a 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
A summary. 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.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Feb 24, 2023 (edit link).