What it is
Rayon turns sequential iterator chains into parallel ones by changing iter() to par_iter(), with work-stealing and guaranteed data-race freedom.
Replace iter with par_iter on CPU-bound work over large collections. Rayon splits the work across a thread pool sized to your cores.
Installation
cargo add rayonGetting started
The smallest useful thing you can do with it, and what each part means.
rust
use rayon::prelude::*;
// Sequential
let total: u64 = values.iter().map(|v| expensive(*v)).sum();
// Parallel — the only change is par_iter
let total: u64 = values.par_iter().map(|v| expensive(*v)).sum();
let matches: Vec<_> = documents
.par_iter()
.filter(|d| d.contains(&needle))
.cloned()
.collect(); // order is preserved
images.par_iter_mut().for_each(|img| img.apply_filter());Advanced usage
Where the library earns its place over a simpler alternative.
rust
// Restrict Rayon so it does not compete with other work.
let pool = rayon::ThreadPoolBuilder::new().num_threads(4).build()?;
let result = pool.install(|| {
data.par_iter()
.fold(Stats::default, |mut acc, item| { acc.add(item); acc })
.reduce(Stats::default, |a, b| a.merge(b))
});
// Parallel sort, and a fallback for small inputs.
let mut items = load();
if items.len() > 10_000 {
items.par_sort_unstable_by_key(|i| i.score);
} else {
items.sort_unstable_by_key(|i| i.score);
}Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- closure may outlive the current function
- The closure borrows a local. Use par_iter on owned data, or scoped threads.
- Parallel is slower than sequential
- The work per item is too small, or a shared lock is serialising it. Increase the chunk of work per item or remove the contention.
Best practices
- Use Rayon for CPU-bound work only — for I/O-bound concurrency use Tokio.
- Measure before adopting: on small collections the overhead dominates.
- Prefer fold/reduce over a shared Mutex, which serialises exactly what you parallelised.
- Constrain the pool size in a server so Rayon does not starve the async runtime.
Background
Why it exists, and what it was reacting to.
Written by Niko Matsakis, Rayon is the clearest demonstration of Rust's fearless concurrency claim: the borrow checker proves the parallel version is safe, so the change really is that small.
