Convert Figma logo to code with AI

rayon-rs logorayon

Rayon: A data parallelism library for Rust

10,805
493
10,805
194

Top Related Projects

26,366

A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...

3,614

A small and fast async runtime for Rust

Async version of the Rust standard library

Compact and efficient synchronization primitives for Rust. Also provides an API for creating custom synchronization primitives.

Quick Overview

Rayon is a data-parallelism library for Rust, designed to make it easy to write efficient parallel programs. It provides a set of high-level APIs that allow developers to parallelize their code with minimal effort, while also offering low-level control for more advanced use cases.

Pros

  • Ease of Use: Rayon's high-level APIs make it simple to parallelize existing code, with minimal changes required.
  • Performance: Rayon is highly optimized and can provide significant performance improvements for many types of parallel computations.
  • Flexibility: Rayon offers both high-level and low-level APIs, allowing developers to choose the level of control that best fits their needs.
  • Scalability: Rayon can effectively utilize multiple cores and processors, making it well-suited for modern hardware.

Cons

  • Complexity: While the high-level APIs are straightforward, the underlying implementation can be complex, which may make it challenging for beginners to fully understand.
  • Overhead: There is some overhead associated with Rayon's parallelization, which may not be suitable for very small tasks or highly sensitive performance requirements.
  • Debugging: Debugging parallel code can be more challenging than sequential code, and Rayon does not provide any special debugging tools or features.
  • Limited Ecosystem: Rayon is a relatively niche library, and the ecosystem of related tools and libraries may not be as extensive as some other Rust libraries.

Code Examples

Parallel Map

use rayon::prelude::*;

let numbers: Vec<i32> = (0..1000).collect();
let squared: Vec<i32> = numbers.par_iter().map(|x| x * x).collect();

This example demonstrates how to use Rayon's par_iter() method to parallelize a simple map operation on a vector of numbers.

Parallel Reduce

use rayon::prelude::*;

let numbers: Vec<i32> = (0..1000).collect();
let sum: i32 = numbers.par_iter().sum();

This example shows how to use Rayon's par_iter() and sum() methods to perform a parallel reduction operation on a vector of numbers.

Parallel Sorting

use rayon::prelude::*;

let mut numbers: Vec<i32> = (0..1000).collect();
numbers.par_sort();

This example demonstrates how to use Rayon's par_sort() method to parallelize the sorting of a vector of numbers.

Getting Started

To use Rayon in your Rust project, add the following to your Cargo.toml file:

[dependencies]
rayon = "1.5.3"

Then, in your Rust code, import the Rayon prelude and start using the parallel APIs:

use rayon::prelude::*;

fn main() {
    let numbers: Vec<i32> = (0..1000).collect();
    let squared: Vec<i32> = numbers.par_iter().map(|x| x * x).collect();
    println!("Squared numbers: {:?}", squared);
}

This will execute the map operation in parallel, taking advantage of the available CPU cores on the system.

Competitor Comparisons

26,366

A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...

Pros of Tokio

  • Asynchronous I/O-focused, ideal for network-heavy applications
  • Supports both multi-threaded and single-threaded runtimes
  • Extensive ecosystem with many compatible libraries

Cons of Tokio

  • Steeper learning curve due to async/await concepts
  • Can introduce complexity for CPU-bound tasks
  • Potential for increased memory usage in some scenarios

Code Comparison

Rayon (parallel iteration):

use rayon::prelude::*;

let result: Vec<i32> = (0..1000).into_par_iter()
    .map(|i| i * i)
    .collect();

Tokio (asynchronous task):

use tokio;

#[tokio::main]
async fn main() {
    let handle = tokio::spawn(async {
        // Asynchronous operation
    });
    handle.await.unwrap();
}

Key Differences

  • Rayon focuses on data parallelism and CPU-bound tasks
  • Tokio specializes in asynchronous I/O and concurrent programming
  • Rayon is generally easier to use for simple parallelization
  • Tokio offers more fine-grained control over task scheduling

Use Cases

  • Rayon: Data processing, parallel algorithms, CPU-intensive computations
  • Tokio: Web servers, network applications, I/O-bound operations

Both libraries have their strengths and are often used in conjunction for different aspects of a Rust application, depending on the specific requirements of each task.

3,614

A small and fast async runtime for Rust

Pros of smol

  • Designed for asynchronous programming, offering better performance for I/O-bound tasks
  • Lightweight and minimal, with a smaller footprint and faster compilation times
  • Provides a more flexible runtime model, allowing for fine-grained control over task execution

Cons of smol

  • Less suitable for CPU-bound tasks compared to Rayon's work-stealing model
  • Requires more manual management of asynchronous tasks and futures
  • Steeper learning curve for developers not familiar with async Rust concepts

Code Comparison

smol example:

use smol::Timer;
use std::time::Duration;

smol::block_on(async {
    Timer::after(Duration::from_secs(1)).await;
    println!("One second has passed");
});

Rayon example:

use rayon::prelude::*;

let result: i32 = (0..1000).into_par_iter()
    .map(|i| i * i)
    .sum();

Summary

smol is better suited for asynchronous, I/O-bound tasks with fine-grained control, while Rayon excels at parallel processing of CPU-bound workloads. smol offers a more lightweight solution but requires more manual management of async tasks. Rayon provides a simpler API for parallelizing computations but may be less efficient for I/O-heavy operations.

Async version of the Rust standard library

Pros of async-std

  • Designed for asynchronous programming, better suited for I/O-bound tasks
  • Provides a familiar interface similar to the Rust standard library
  • Offers more fine-grained control over task execution

Cons of async-std

  • Higher learning curve due to async/await concepts
  • Potential for increased complexity in code structure
  • May have slightly higher overhead for CPU-bound tasks

Code Comparison

async-std example:

use async_std::task;

async fn example() {
    println!("Hello, world!");
}

fn main() {
    task::block_on(example());
}

Rayon example:

use rayon::prelude::*;

fn main() {
    (0..100).into_par_iter()
        .for_each(|i| println!("Number: {}", i));
}

Key Differences

  • async-std focuses on asynchronous programming, while Rayon specializes in parallel computing
  • Rayon is generally simpler to use for CPU-bound tasks and data parallelism
  • async-std is more versatile for I/O-bound operations and concurrent programming

Use Cases

  • Choose async-std for network operations, file I/O, or when dealing with many concurrent tasks
  • Opt for Rayon when working with CPU-intensive computations or data processing on multi-core systems

Both libraries have their strengths, and the choice depends on the specific requirements of your project and the nature of the tasks you need to parallelize or make asynchronous.

Compact and efficient synchronization primitives for Rust. Also provides an API for creating custom synchronization primitives.

Pros of parking_lot

  • Focused on efficient synchronization primitives, offering better performance for low-contention scenarios
  • Provides more compact mutex and rwlock implementations, reducing memory usage
  • Offers additional synchronization types like Condvar and Once

Cons of parking_lot

  • Limited to synchronization primitives, lacking the parallel processing capabilities of Rayon
  • May require more manual implementation for complex parallel tasks
  • Less suitable for CPU-bound workloads that benefit from work-stealing

Code Comparison

parking_lot:

use parking_lot::Mutex;

let mutex = Mutex::new(0);
*mutex.lock() += 1;

Rayon:

use rayon::prelude::*;

let result: i32 = (0..1000).into_par_iter().sum();

Summary

parking_lot excels in providing efficient, low-level synchronization primitives, while Rayon offers high-level parallel processing capabilities. parking_lot is ideal for scenarios requiring fine-grained control over synchronization, whereas Rayon shines in easily parallelizing data processing tasks. The choice between them depends on the specific requirements of your project, with parking_lot being more suitable for low-level concurrent operations and Rayon for high-level parallel computations.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Rayon

Rayon crate Rayon documentation minimum rustc 1.63 build status Join the chat at https://gitter.im/rayon-rs/Lobby

Rayon is a data-parallelism library for Rust. It is extremely lightweight and makes it easy to convert a sequential computation into a parallel one. It also guarantees data-race freedom. (You may also enjoy this blog post about Rayon, which gives more background and details about how it works, or this video, from the Rust Belt Rust conference.) Rayon is available on crates.io, and API documentation is available on docs.rs.

Parallel iterators and more

Rayon makes it drop-dead simple to convert sequential iterators into parallel ones: usually, you just change your foo.iter() call into foo.par_iter(), and Rayon does the rest:

use rayon::prelude::*;
fn sum_of_squares(input: &[i32]) -> i32 {
    input.par_iter() // <-- just change that!
         .map(|&i| i * i)
         .sum()
}

Parallel iterators take care of deciding how to divide your data into tasks; it will dynamically adapt for maximum performance. If you need more flexibility than that, Rayon also offers the join and scope functions, which let you create parallel tasks on your own. For even more control, you can create custom threadpools rather than using Rayon's default, global threadpool.

No data races

You may have heard that parallel execution can produce all kinds of crazy bugs. Well, rest easy. Rayon's APIs all guarantee data-race freedom, which generally rules out most parallel bugs (though not all). In other words, if your code compiles, it typically does the same thing it did before.

For the most, parallel iterators in particular are guaranteed to produce the same results as their sequential counterparts. One caveat: If your iterator has side effects (for example, sending methods to other threads through a Rust channel or writing to disk), those side effects may occur in a different order. Note also that, in some cases, parallel iterators offer alternative versions of the sequential iterator methods that can have higher performance.

Using Rayon

Rayon is available on crates.io. The recommended way to use it is to add a line into your Cargo.toml such as:

[dependencies]
rayon = "1.10"

To use the parallel iterator APIs, a number of traits have to be in scope. The easiest way to bring those things into scope is to use the Rayon prelude. In each module where you would like to use the parallel iterator APIs, just add:

use rayon::prelude::*;

Rayon currently requires rustc 1.63.0 or greater.

Usage with WebAssembly

By default, when building to WebAssembly, Rayon will treat it as any other platform without multithreading support and will fall back to sequential iteration. This allows existing code to compile and run successfully with no changes necessary, but it will run slower as it will only use a single CPU core.

You can build Rayon-based projects with proper multithreading support for the Web, but you'll need an adapter and some project configuration to account for differences between WebAssembly threads and threads on the other platforms.

Check out the wasm-bindgen-rayon docs for more details.

Contribution

Rayon is an open source project! If you'd like to contribute to Rayon, check out the list of "help wanted" issues. These are all (or should be) issues that are suitable for getting started, and they generally include a detailed set of instructions for what to do. Please ask questions if anything is unclear! Also, check out the Guide to Development page on the wiki. Note that all code submitted in PRs to Rayon is assumed to be licensed under Rayon's dual MIT/Apache 2.0 licensing.

Quick demo

To see Rayon in action, check out the rayon-demo directory, which includes a number of demos of code using Rayon. For example, run this command to get a visualization of an N-body simulation. To see the effect of using Rayon, press s to run sequentially and p to run in parallel.

> cd rayon-demo
> cargo run --release -- nbody visualize

For more information on demos, try:

> cd rayon-demo
> cargo run --release -- --help

Other questions?

See the Rayon FAQ.

License

Rayon is distributed under the terms of both the MIT license and the Apache License (Version 2.0). See LICENSE-APACHE and LICENSE-MIT for details. Opening a pull request is assumed to signal agreement with these licensing terms.