Skip to content

Instantly share code, notes, and snippets.

@SCP002
Last active November 27, 2023 08:12
Show Gist options
  • Save SCP002/653515996e8f924f927507500694d77d to your computer and use it in GitHub Desktop.
Save SCP002/653515996e8f924f927507500694d77d to your computer and use it in GitHub Desktop.
Rust: concurrent filter example. Keeps empty elements and original order. Using thread pool.
// Add to your Cargo.toml:
// [dependencies]
// rayon = "1.1"
use rayon::prelude::*;
use rayon::ThreadPoolBuilder;
use std::thread;
use std::time::{Duration, Instant};
fn main() {
let input = vec!["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "", ""];
let expected = vec!["B", "D", "F", "H", "J", ""];
/// Returns true if item should stay in the collection given to filter
///
/// # Arguments
///
/// * `item` - A tuple with current index and element of the collection
fn keep_fn(item: &(usize, &&str)) -> bool {
thread::sleep(Duration::from_secs(3)); // Sleep for 3 seconds to simulate heavy task.
item.0 % 2 != 0 // Keep every even element (remove every odd).
}
let max_workers = 6;
let pool = ThreadPoolBuilder::new().num_threads(max_workers).build().unwrap();
let start = Instant::now();
let output: Vec<&str> = pool.scope(|_| {
input
.par_iter()
.enumerate()
.filter(keep_fn)
.map(|(_, e)| *e)
.collect()
});
let duration = start.elapsed();
println!("Filtering took {:?}", duration);
if output != expected {
println!("Unexpected output {:?}", output);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment