From: MA Beaudet Date: Sun, 14 Nov 2021 20:56:10 +0000 (+0100) Subject: fix(rayon): remove mutexes in favor of fold for counters X-Git-Url: https://git.beaudet.xyz/?a=commitdiff_plain;h=eadb1ff250787f24aee407c591d9c14585f06e69;p=poker-eval.git fix(rayon): remove mutexes in favor of fold for counters --- diff --git a/src/lib.rs b/src/lib.rs index 28deb5c..4db01e0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -379,30 +379,40 @@ pub fn parallel_deck_freq_evaluator(deck: &[u32]) -> [u32; 10] { } /// 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)]