diff options
Diffstat (limited to 'benches/sync_rwlock.rs')
-rw-r--r-- | benches/sync_rwlock.rs | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/benches/sync_rwlock.rs b/benches/sync_rwlock.rs new file mode 100644 index 00000000..4eca9807 --- /dev/null +++ b/benches/sync_rwlock.rs @@ -0,0 +1,147 @@ +use bencher::{black_box, Bencher}; +use std::sync::Arc; +use tokio::{sync::RwLock, task}; + +fn read_uncontended(b: &mut Bencher) { + let mut rt = tokio::runtime::Builder::new() + .core_threads(6) + .threaded_scheduler() + .build() + .unwrap(); + + let lock = Arc::new(RwLock::new(())); + b.iter(|| { + let lock = lock.clone(); + rt.block_on(async move { + for _ in 0..6 { + let read = lock.read().await; + black_box(read); + } + }) + }); +} + +fn read_concurrent_uncontended_multi(b: &mut Bencher) { + let mut rt = tokio::runtime::Builder::new() + .core_threads(6) + .threaded_scheduler() + .build() + .unwrap(); + + async fn task(lock: Arc<RwLock<()>>) { + let read = lock.read().await; + black_box(read); + } + + let lock = Arc::new(RwLock::new(())); + b.iter(|| { + let lock = lock.clone(); + rt.block_on(async move { + let j = tokio::try_join! { + task::spawn(task(lock.clone())), + task::spawn(task(lock.clone())), + task::spawn(task(lock.clone())), + task::spawn(task(lock.clone())), + task::spawn(task(lock.clone())), + task::spawn(task(lock.clone())) + }; + j.unwrap(); + }) + }); +} + +fn read_concurrent_uncontended(b: &mut Bencher) { + let mut rt = tokio::runtime::Builder::new() + .basic_scheduler() + .build() + .unwrap(); + + async fn task(lock: Arc<RwLock<()>>) { + let read = lock.read().await; + black_box(read); + } + + let lock = Arc::new(RwLock::new(())); + b.iter(|| { + let lock = lock.clone(); + rt.block_on(async move { + tokio::join! { + task(lock.clone()), + task(lock.clone()), + task(lock.clone()), + task(lock.clone()), + task(lock.clone()), + task(lock.clone()) + }; + }) + }); +} + +fn read_concurrent_contended_multi(b: &mut Bencher) { + let mut rt = tokio::runtime::Builder::new() + .core_threads(6) + .threaded_scheduler() + .build() + .unwrap(); + + async fn task(lock: Arc<RwLock<()>>) { + let read = lock.read().await; + black_box(read); + } + + let lock = Arc::new(RwLock::new(())); + b.iter(|| { + let lock = lock.clone(); + rt.block_on(async move { + let write = lock.write().await; + let j = tokio::try_join! { + async move { drop(write); Ok(()) }, + task::spawn(task(lock.clone())), + task::spawn(task(lock.clone())), + task::spawn(task(lock.clone())), + task::spawn(task(lock.clone())), + task::spawn(task(lock.clone())), + }; + j.unwrap(); + }) + }); +} + +fn read_concurrent_contended(b: &mut Bencher) { + let mut rt = tokio::runtime::Builder::new() + .basic_scheduler() + .build() + .unwrap(); + + async fn task(lock: Arc<RwLock<()>>) { + let read = lock.read().await; + black_box(read); + } + + let lock = Arc::new(RwLock::new(())); + b.iter(|| { + let lock = lock.clone(); + rt.block_on(async move { + let write = lock.write().await; + tokio::join! { + async move { drop(write) }, + task(lock.clone()), + task(lock.clone()), + task(lock.clone()), + task(lock.clone()), + task(lock.clone()), + }; + }) + }); +} + +bencher::benchmark_group!( + sync_rwlock, + read_uncontended, + read_concurrent_uncontended, + read_concurrent_uncontended_multi, + read_concurrent_contended, + read_concurrent_contended_multi +); + +bencher::benchmark_main!(sync_rwlock); |