#![allow(missing_docs, reason = "No need for API documentation in example code")]
use std::collections::HashMap;
use std::hint::black_box;
use std::sync::{Arc, RwLock};
use criterion::{Criterion, criterion_group, criterion_main};
use many_cpus_benchmarking::{Payload, WorkDistribution, execute_runs};
criterion_group!(benches, entrypoint);
criterion_main!(benches);
fn entrypoint(c: &mut Criterion) {
execute_runs::<SharedHashMapRead<1024, 10>, 100>(
c,
WorkDistribution::all_with_unique_processors_without_self(),
);
}
const _MAP_ENTRY_COUNT: usize = 1024;
const _REPEAT_COUNT: usize = 10;
#[derive(Debug, Default)]
struct SharedHashMapRead<const MAP_ENTRY_COUNT: usize, const REPEAT_COUNT: usize> {
map: Arc<RwLock<HashMap<u64, u64>>>,
is_initializer: bool,
}
impl<const MAP_ENTRY_COUNT: usize, const REPEAT_COUNT: usize> Payload
for SharedHashMapRead<MAP_ENTRY_COUNT, REPEAT_COUNT>
{
fn new_pair() -> (Self, Self) {
let map = Arc::new(RwLock::new(HashMap::with_capacity(MAP_ENTRY_COUNT)));
let worker1 = Self {
map: Arc::clone(&map),
is_initializer: true,
};
let worker2 = Self {
map,
is_initializer: false,
};
(worker1, worker2)
}
fn prepare(&mut self) {
if !self.is_initializer {
return;
}
let mut map = self.map.write().unwrap();
for i in 0..MAP_ENTRY_COUNT {
map.insert(i as u64, i.wrapping_mul(2) as u64);
}
}
fn process(&mut self) {
let map = self.map.read().unwrap();
for _ in 0..REPEAT_COUNT {
for key in 0..MAP_ENTRY_COUNT {
black_box(map.get(&(key as u64)));
}
}
}
}