summaryrefslogtreecommitdiffstats
path: root/vendor/sharded-slab/benches
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /vendor/sharded-slab/benches
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--vendor/sharded-slab/benches/bench.rs181
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);