Просмотр исходного кода

bench: crossbeam benchmark add reads

darkfi 2 лет назад
Родитель
Сommit
4a77e172c2
1 измененных файлов с 83 добавлено и 2 удалено
  1. 83 2
      bench/crossbeam.rs

+ 83 - 2
bench/crossbeam.rs

@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion};
+use criterion::{black_box, criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion};
 use crossbeam_skiplist::SkipMap;
 use easy_parallel::Parallel;
 use rand::{rngs::OsRng, Rng};
@@ -29,7 +29,7 @@ use std::{
 };
 
 fn crossbeam(c: &mut Criterion) {
-    let mut group = c.benchmark_group("crossbeam_vs_mutex-hashmap");
+    let mut group = c.benchmark_group("crossbeam_vs_mutex-hashmap_writes");
 
     for k in 1..10 {
         let stopped = Arc::new(AtomicBool::new(false));
@@ -116,6 +116,87 @@ fn crossbeam(c: &mut Criterion) {
         stopped.store(true, Ordering::Relaxed);
         parallel_inserts.join().unwrap();
     }
+
+    group.finish();
+
+    let mut group = c.benchmark_group("crossbeam_vs_mutex-hashmap_reads");
+
+    for k in 1..10 {
+        let stopped = Arc::new(AtomicBool::new(false));
+        let map = Arc::new(SkipMap::new());
+
+        let stopped2 = stopped.clone();
+        let map2 = map.clone();
+
+        // Start n threads all doing continuous inserts until we tell them to stop
+        let parallel_inserts = std::thread::spawn(move || {
+            Parallel::new()
+                .each(0..k, |_| {
+                    let stopped = stopped2.clone();
+                    let map = map2.clone();
+
+                    while !stopped.load(Ordering::Relaxed) {
+                        let key: usize = OsRng.gen();
+                        let val: usize = OsRng.gen();
+                        map.insert(key, val);
+                    }
+                })
+                .run();
+        });
+
+        group.bench_with_input(BenchmarkId::new("crossbeam", k), &k, |b, &_| {
+            b.iter(|| {
+                for entry in map.iter().take(100) {
+                    let key = entry.key();
+                    let val = entry.value();
+                    black_box((key, val));
+                }
+            })
+        });
+
+        stopped.store(true, Ordering::Relaxed);
+        parallel_inserts.join().unwrap();
+    }
+
+    // Now try normal Mutex hashmap
+    // This is not an async Mutex, but async Mutexes are always slower than sync ones anyway
+    // since they just implement an async interface on top of sync Mutexes.
+
+    for k in 1..10 {
+        let stopped = Arc::new(AtomicBool::new(false));
+        let map = Arc::new(Mutex::new(HashMap::new()));
+
+        let stopped2 = stopped.clone();
+        let map2 = map.clone();
+
+        // Start n threads all doing continuous inserts until we tell them to stop
+        let parallel_inserts = std::thread::spawn(move || {
+            Parallel::new()
+                .each(0..k, |_| {
+                    let stopped = stopped2.clone();
+                    let map = map2.clone();
+
+                    while !stopped.load(Ordering::Relaxed) {
+                        let key: usize = OsRng.gen();
+                        let val: usize = OsRng.gen();
+                        map.lock().unwrap().insert(key, val);
+                    }
+                })
+                .run();
+        });
+
+        group.bench_with_input(BenchmarkId::new("mutex_hashmap", k), &k, |b, &_| {
+            b.iter(|| {
+                for (key, val) in map.lock().unwrap().iter().take(100) {
+                    // Do nothing
+                    black_box((key, val));
+                }
+            })
+        });
+
+        stopped.store(true, Ordering::Relaxed);
+        parallel_inserts.join().unwrap();
+    }
 }
 
 criterion_group!(bench, crossbeam);