diff options
Diffstat (limited to '')
-rw-r--r-- | vendor/sharded-slab/benches/bench.rs | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/vendor/sharded-slab/benches/bench.rs b/vendor/sharded-slab/benches/bench.rs new file mode 100644 index 000000000..c95bd4e38 --- /dev/null +++ b/vendor/sharded-slab/benches/bench.rs @@ -0,0 +1,181 @@ +use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; +use std::{ + sync::{Arc, Barrier, RwLock}, + thread, + time::{Duration, Instant}, +}; + +#[derive(Clone)] +struct MultithreadedBench<T> { + start: Arc<Barrier>, + end: Arc<Barrier>, + slab: Arc<T>, +} + +impl<T: Send + Sync + 'static> MultithreadedBench<T> { + fn new(slab: Arc<T>) -> Self { + Self { + start: Arc::new(Barrier::new(5)), + end: Arc::new(Barrier::new(5)), + slab, + } + } + + fn thread(&self, f: impl FnOnce(&Barrier, &T) + Send + 'static) -> &Self { + let start = self.start.clone(); + let end = self.end.clone(); + let slab = self.slab.clone(); + thread::spawn(move || { + f(&*start, &*slab); + end.wait(); + }); + self + } + + fn run(&self) -> Duration { + self.start.wait(); + let t0 = Instant::now(); + self.end.wait(); + t0.elapsed() + } +} + +const N_INSERTIONS: &[usize] = &[100, 300, 500, 700, 1000, 3000, 5000]; + +fn insert_remove_local(c: &mut Criterion) { + // the 10000-insertion benchmark takes the `slab` crate about an hour to + // run; don't run this unless you're prepared for that... + // const N_INSERTIONS: &'static [usize] = &[100, 500, 1000, 5000, 10000]; + let mut group = c.benchmark_group("insert_remove_local"); + let g = group.measurement_time(Duration::from_secs(15)); + + for i in N_INSERTIONS { + g.bench_with_input(BenchmarkId::new("sharded_slab", i), i, |b, &i| { + b.iter_custom(|iters| { + let mut total = Duration::from_secs(0); + for _ in 0..iters { + let bench = MultithreadedBench::new(Arc::new(sharded_slab::Slab::new())); + let elapsed = bench + .thread(move |start, slab| { + start.wait(); + let v: Vec<_> = (0..i).map(|i| slab.insert(i).unwrap()).collect(); + for i in v { + slab.remove(i); + } + }) + .thread(move |start, slab| { + start.wait(); + let v: Vec<_> = (0..i).map(|i| slab.insert(i).unwrap()).collect(); + for i in v { + slab.remove(i); + } + }) + .thread(move |start, slab| { + start.wait(); + let v: Vec<_> = (0..i).map(|i| slab.insert(i).unwrap()).collect(); + for i in v { + slab.remove(i); + } + }) + .thread(move |start, slab| { + start.wait(); + let v: Vec<_> = (0..i).map(|i| slab.insert(i).unwrap()).collect(); + for i in v { + slab.remove(i); + } + }) + .run(); + total += elapsed; + } + total + }) + }); + g.bench_with_input(BenchmarkId::new("slab_biglock", i), i, |b, &i| { + b.iter_custom(|iters| { + let mut total = Duration::from_secs(0); + let i = i; + for _ in 0..iters { + let bench = MultithreadedBench::new(Arc::new(RwLock::new(slab::Slab::new()))); + let elapsed = bench + .thread(move |start, slab| { + start.wait(); + let v: Vec<_> = + (0..i).map(|i| slab.write().unwrap().insert(i)).collect(); + for i in v { + slab.write().unwrap().remove(i); + } + }) + .thread(move |start, slab| { + start.wait(); + let v: Vec<_> = + (0..i).map(|i| slab.write().unwrap().insert(i)).collect(); + for i in v { + slab.write().unwrap().remove(i); + } + }) + .thread(move |start, slab| { + start.wait(); + let v: Vec<_> = + (0..i).map(|i| slab.write().unwrap().insert(i)).collect(); + for i in v { + slab.write().unwrap().remove(i); + } + }) + .thread(move |start, slab| { + start.wait(); + let v: Vec<_> = + (0..i).map(|i| slab.write().unwrap().insert(i)).collect(); + for i in v { + slab.write().unwrap().remove(i); + } + }) + .run(); + total += elapsed; + } + total + }) + }); + } + group.finish(); +} + +fn insert_remove_single_thread(c: &mut Criterion) { + // the 10000-insertion benchmark takes the `slab` crate about an hour to + // run; don't run this unless you're prepared for that... + // const N_INSERTIONS: &'static [usize] = &[100, 500, 1000, 5000, 10000]; + let mut group = c.benchmark_group("insert_remove_single_threaded"); + + for i in N_INSERTIONS { + group.bench_with_input(BenchmarkId::new("sharded_slab", i), i, |b, &i| { + let slab = sharded_slab::Slab::new(); + b.iter(|| { + let v: Vec<_> = (0..i).map(|i| slab.insert(i).unwrap()).collect(); + for i in v { + slab.remove(i); + } + }); + }); + group.bench_with_input(BenchmarkId::new("slab_no_lock", i), i, |b, &i| { + let mut slab = slab::Slab::new(); + b.iter(|| { + let v: Vec<_> = (0..i).map(|i| slab.insert(i)).collect(); + for i in v { + slab.remove(i); + } + }); + }); + group.bench_with_input(BenchmarkId::new("slab_uncontended", i), i, |b, &i| { + let slab = RwLock::new(slab::Slab::new()); + b.iter(|| { + let v: Vec<_> = (0..i).map(|i| slab.write().unwrap().insert(i)).collect(); + for i in v { + slab.write().unwrap().remove(i); + } + }); + }); + } + group.finish(); +} + +criterion_group!(benches, insert_remove_local, insert_remove_single_thread); +criterion_main!(benches); |