Home
Rust
skip, take Examples
Updated Jan 29, 2023
Dot Net Perls
Skip, take. In Rust we can use the skip and take functions to advance to a position in an iterator. The clippy tool recommends skip and take.
With these functions, we narrow down the range of an iter(). We usually need to call iter() first to use skip and take. These functions affect loop performance.
iter
Skip example. To begin, we create an array of 4 numbers. We get an iterator from the array by calling iter() in the for-loop. We print out the values looped over.
for
And We call skip() with an argument of 2 on the return value of iter(). This skips over 2 elements from the start.
Result When we call skip() with an argument of 2, we access just the third and fourth elements, 30 and 40.
fn main() { // Source array. let values = [10, 20, 30, 40]; // Loop starting past the first 2 items. for value in values.iter().skip(2) { println!("SKIP 2 FROM {:?} = {}", values, value); } }
SKIP 2 FROM [10, 20, 30, 40] = 30 SKIP 2 FROM [10, 20, 30, 40] = 40
Take. With take() we iterate over the first elements of a collection like an array. We specify the number of elements we wish to loop over.
Here We combine skip and take. This allows us to loop over only some of the middle elements in an array.
fn main() { let numbers = [5, 10, 20, 40]; // Loop over first 2 numbers. for number in numbers.iter().take(2) { println!("TAKE 2: {number}"); } // Combine skip and take. for number in numbers.iter().skip(1).take(2) { println!("SKIP 1 TAKE 2: {number}"); } }
TAKE 2: 5 TAKE 2: 10 SKIP 1 TAKE 2: 10 SKIP 1 TAKE 2: 20
Skip benchmark. The clippy tool recommends using skip and take instead of for-range loops. But does this improve performance? We test skip and take performance here.
Version 1 This version of the code uses a for-loop over a range of indexes. It then tests the vector elements.
Version 2 This code uses a for-loop but uses skip and take instead of a range of indexes. It has the same effect as version 1.
Result Using skip() and take() on a loop seems to reduce performance. Just accessing indexes directly is faster.
use std::time::*; fn main() { if let Ok(max) = "20000".parse() { if let Ok(offset) = "20".parse::<usize>() { let top_offset = max - offset; // Sample vector. let mut source = vec![]; for _ in 0..max { source.push(0); } source[5000] = 1; let mut sum1 = 0; let mut sum2 = 0; // Version 1: range loop. let t0 = Instant::now(); for _ in 0..max { for i in offset..top_offset { if source[i] == 1 { sum1 += 1; } } } println!("{}", t0.elapsed().as_millis()); // Version 2: take and skip. let t1 = Instant::now(); for _ in 0..max { for element in source.iter().take(top_offset).skip(offset) { if *element == 1 { sum2 += 1; } } } println!("{}", t1.elapsed().as_millis()); println!("{} = {}", sum1, sum2); } } }
222 249 20000 = 20000
Loop optimization. In my tests, using skip and take with iter() is slower than accessing indexes from a range directly. And using get_unchecked with a range is the fastest approach.
get_unchecked
A summary. A main goal of using Rust is to achieve excellent performance. With skip and take, we can narrow down a loop in a safe way. But unsafe code, and direct index accesses, may be faster.
Dot Net Perls is a collection of pages with code examples, which are updated to stay current. Programming is an art, and it can be learned from examples.
Donate to this site to help offset the costs of running the server. Sites like this will cease to exist if there is no financial support for them.
Sam Allen is passionate about computer languages, and he maintains 100% of the material available on this website. He hopes it makes the world a nicer place.
This page was last updated on Jan 29, 2023 (new example).
Home
Changes
© 2007-2025 Sam Allen