Rayon library already implemented the partition function, and it only divides a vector into two parts, but I need three parts. I code this:
use rayon::prelude::*;
trait IterExt<T> {
fn for_each(self, f: impl Fn(T) + Sync + Send);
fn partition3(self, predicate1: impl FnMut(&T) -> bool + Sync + Send, predicate2: impl FnMut(&T) -> bool + Sync + Send) -> (Vec<T>, Vec<T>, Vec<T>) where T: Sync;
}
impl<T> IterExt<T> for Vec<T> where T: Send {
fn for_each(self, f: impl Fn(T) + Sync + Send) {
self.into_par_iter().for_each(f);
}
fn partition3(self, mut predicate1: impl FnMut(&T) -> bool + Sync + Send, mut predicate2: impl FnMut(&T) -> bool + Sync + Send) -> (Vec<T>, Vec<T>, Vec<T>) where T: Sync {
let mut first = vec![];
let mut second = vec![];
let mut third = vec![];
self.for_each(|e|
if predicate1(&e) { first.push(e) }
else if predicate2(&e) { second.push(e) }
else { third.push(e) }
);
(first, second, third)
}
}
I tried to write for a long time, but still got stuck in borrow checker.
I want to know how to write a correct parallel function to divide a vector into three parts.
1
共 1 条评论, 1 页
评论区
写评论I don't think you can declare
predicate1andpredicate2asFnMut. When rayon executes the partition parallelly, different threads may need to callpredicate1at the same time, which violates the borrow rule since it requires a mutable reference topredicate1to call throughFnMut.What you should do is to make predicates
Fn, and use interior mutability and proper synchronization if mutation is needed.PS: use
partition_mapto partition into multiple collections.