Rust extend from slice Example (Benchmark)Use the extend from slice function to add one slice to another. Benchmark slice-appending functions.
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.
push u8 Vec
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).
First 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.
Rust program that appends vector to vector
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()); }
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.
Rust program that times Vec extend_from_slice, push
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.
© 2007-2022 sam allen.
see site info on the changelog.