BudiBadu Logo
Samplebadu

Rust by Example: Rayon Parallel Iterators

Rust 1.75+

Unlock easy data parallelism with Rayon. This example shows how to convert sequential iterators into parallel ones with a single method call, utilizing all CPU cores for data processing tasks.

Code

use rayon::prelude::*;

fn main() {
    let mut vec = vec![0; 100_000];
    
    // Initialize vector sequentially
    for i in 0..vec.len() {
        vec[i] = i;
    }

    // --- Sequential Processing ---
    // sum_of_squares_seq(&vec);

    // --- Parallel Processing ---
    // Rayon makes it trivial to parallelize iterator chains.
    // Just change .iter() to .par_iter()!
    let sum: u64 = vec.par_iter()
                      .map(|&i| i as u64 * i as u64)
                      .sum();

    println!("Sum of squares: {}", sum);
    
    // Parallel sort
    let mut unsorted = vec![5, 1, 3, 2, 4];
    unsorted.par_sort();
    println!("Sorted: {:?}", unsorted);
    
    // Finding an item in parallel
    let found = vec.par_iter().find_any(|&&x| x == 50_000);
    println!("Found: {:?}", found);
}

Explanation

Rayon is the standard library for data parallelism in Rust. It is incredibly lightweight and makes it easy to convert sequential computations into parallel ones. The core idea is that Rayon provides parallel versions of standard iterators, allowing you to use methods like map, filter, and reduce across multiple threads.

By simply importing rayon::prelude::* and changing iter() to par_iter(), Rayon automatically splits your data into chunks and processes them across all available CPU cores. It uses a technique called Work Stealing to balance the load dynamically: if one core finishes its chunk early, it "steals" work from another busy core's queue, ensuring high utilization.

Rayon guarantees data safety. You cannot accidentally introduce data races because Rayon's APIs require the closures you pass to be thread-safe (implementing Send and Sync). If your code compiles with Rayon, it is safe to run in parallel.

Code Breakdown

1
use rayon::prelude::*;. This import brings the ParallelIterator trait methods into scope, allowing you to call par_iter, par_sort, etc. on standard collections.
17
vec.par_iter(). Creates a parallel iterator. Subsequent operations like map and sum will be executed in parallel. The results are combined automatically by Rayon.
26
unsorted.par_sort(). A parallel merge sort. For large datasets, this is significantly faster than the standard sequential sort.
29
find_any(...). Unlike sequential find which returns the first match, find_any returns any match it finds. This allows Rayon to stop searching as soon as any thread finds the item, without needing to coordinate order.