}
/// Concurrent evaluation of all five-card poker hands using rayon crate.
-///
-/// This implementation is actually slower in release builds.
#[cfg(feature = "rayon")]
pub fn concurrent_deck_freq_evaluator(deck: &[u32]) -> [u32; 10] {
- use rayon::prelude::*;
+ use std::sync::mpsc;
- let freq: Mutex<[u32; 10]> = Mutex::new([0; 10]);
+ fn fold_counters(mut acc: [u32; 10], count: [u32; 10]) -> [u32; 10] {
+ count.iter().enumerate().for_each(|(k, v)| acc[k] += v);
+ acc
+ }
- (0..48).into_par_iter().for_each(|a| {
- for b in a + 1..49 {
- for c in b + 1..50 {
- for d in c + 1..51 {
- for e in d + 1..52 {
- let i = eval_5hand(&[deck[a], deck[b], deck[c], deck[d], deck[e]]);
- let j = hand_rank(i);
- let mut freq = freq.lock().unwrap();
- freq[j as usize] += 1;
+ let (tx, rx) = mpsc::channel();
+
+ rayon::scope(move |scope| {
+ for a in (0..48).into_iter() {
+ let tx = tx.clone();
+ scope.spawn(move |_| {
+ // let mut freq = HashMap::new();
+ let mut freq = [0; 10];
+ for b in a + 1..49 {
+ for c in b + 1..50 {
+ for d in c + 1..51 {
+ for e in d + 1..52 {
+ let i = eval_5hand(&[deck[a], deck[b], deck[c], deck[d], deck[e]]);
+ let j = hand_rank(i);
+ freq[j as usize] += 1;
+ // *freq.entry(j).or_insert(0) += 1;
+ }
+ }
}
}
- }
+ let _ = tx.send(freq);
+ });
}
});
- let x = *freq.lock().unwrap();
- x
+ rx.into_iter().fold([0; 10], fold_counters)
}
#[cfg(test)]