use std::{
collections::HashMap,
convert::{TryFrom, TryInto},
- sync::{Arc, Mutex},
thread,
};
}
/// Concurrent evaluation of all five-card poker hands.
-///
-/// This implementation is actually slower in release builds.
-/// This is probably due to the Mutex wrap on `freq`.
pub fn parallel_deck_freq_evaluator(deck: &[u32]) -> [u32; 10] {
+ use std::sync::{mpsc, Arc};
+
+ fn fold_counters(mut acc: [u32; 10], count: [u32; 10]) -> [u32; 10] {
+ count.iter().enumerate().for_each(|(k, v)| acc[k] += v);
+ acc
+ }
+
let deck = Arc::new(Vec::from(deck));
- let freq: Arc<Mutex<[u32; 10]>> = Arc::new(Mutex::new([0; 10]));
- let thread_vec = (0..48).collect::<Vec<_>>();
- let mut thread_handles = vec![];
-
- for v in thread_vec.chunks(6) {
- let v = v.to_owned();
- let deck = deck.clone();
- let freq = freq.clone();
- thread_handles.push(thread::spawn(move || {
- for a in v {
- 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;
+
+ // tx goes out of scope before folding counters
+ // Otherwise you would need to explicitly call `drop(tx)`
+ let rx = {
+ let (tx, rx) = mpsc::channel();
+
+ let thread_vec: Vec<usize> = (0..48).into_iter().collect();
+ for v in thread_vec.chunks(6) {
+ let v = v.to_owned();
+ let deck = deck.clone();
+ let tx = tx.clone();
+ thread::spawn(move || {
+ let mut freq = [0; 10];
+ for a in v.clone() {
+ 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;
+ }
}
}
}
}
- }
- }));
- }
-
- for handle in thread_handles {
- handle.join().unwrap();
- }
- let freq = *freq.lock().unwrap();
- freq
+ let _ = tx.send(freq);
+ });
+ }
+ rx
+ };
+ // drop(tx);
+ rx.iter().fold([0; 10], fold_counters)
}
/// Concurrent evaluation of all five-card poker hands using rayon crate.