1use std::sync::Arc;
2use tokio::{sync::RwLock, task};
3
4use criterion::measurement::WallTime;
5use criterion::{black_box, criterion_group, criterion_main, BenchmarkGroup, Criterion};
6
7fn read_uncontended(g: &mut BenchmarkGroup<WallTime>) {
8 let rt = tokio::runtime::Builder::new_multi_thread()
9 .worker_threads(6)
10 .build()
11 .unwrap();
12
13 let lock = Arc::new(RwLock::new(()));
14 g.bench_function("read", |b| {
15 b.iter(|| {
16 let lock = lock.clone();
17 rt.block_on(async move {
18 for _ in 0..6 {
19 let read = lock.read().await;
20 let _read = black_box(read);
21 }
22 })
23 })
24 });
25}
26
27fn read_concurrent_uncontended_multi(g: &mut BenchmarkGroup<WallTime>) {
28 let rt = tokio::runtime::Builder::new_multi_thread()
29 .worker_threads(6)
30 .build()
31 .unwrap();
32
33 async fn task(lock: Arc<RwLock<()>>) {
34 let read = lock.read().await;
35 let _read = black_box(read);
36 }
37
38 let lock = Arc::new(RwLock::new(()));
39 g.bench_function("read_concurrent_multi", |b| {
40 b.iter(|| {
41 let lock = lock.clone();
42 rt.block_on(async move {
43 let j = tokio::try_join! {
44 task::spawn(task(lock.clone())),
45 task::spawn(task(lock.clone())),
46 task::spawn(task(lock.clone())),
47 task::spawn(task(lock.clone())),
48 task::spawn(task(lock.clone())),
49 task::spawn(task(lock.clone()))
50 };
51 j.unwrap();
52 })
53 })
54 });
55}
56
57fn read_concurrent_uncontended(g: &mut BenchmarkGroup<WallTime>) {
58 let rt = tokio::runtime::Builder::new_current_thread()
59 .build()
60 .unwrap();
61
62 async fn task(lock: Arc<RwLock<()>>) {
63 let read = lock.read().await;
64 let _read = black_box(read);
65 }
66
67 let lock = Arc::new(RwLock::new(()));
68 g.bench_function("read_concurrent", |b| {
69 b.iter(|| {
70 let lock = lock.clone();
71 rt.block_on(async move {
72 tokio::join! {
73 task(lock.clone()),
74 task(lock.clone()),
75 task(lock.clone()),
76 task(lock.clone()),
77 task(lock.clone()),
78 task(lock.clone())
79 };
80 })
81 })
82 });
83}
84
85fn read_concurrent_contended_multi(g: &mut BenchmarkGroup<WallTime>) {
86 let rt = tokio::runtime::Builder::new_multi_thread()
87 .worker_threads(6)
88 .build()
89 .unwrap();
90
91 async fn task(lock: Arc<RwLock<()>>) {
92 let read = lock.read().await;
93 let _read = black_box(read);
94 }
95
96 let lock = Arc::new(RwLock::new(()));
97 g.bench_function("read_concurrent_multi", |b| {
98 b.iter(|| {
99 let lock = lock.clone();
100 rt.block_on(async move {
101 let write = lock.write().await;
102 let j = tokio::try_join! {
103 async move { drop(write); Ok(()) },
104 task::spawn(task(lock.clone())),
105 task::spawn(task(lock.clone())),
106 task::spawn(task(lock.clone())),
107 task::spawn(task(lock.clone())),
108 task::spawn(task(lock.clone())),
109 };
110 j.unwrap();
111 })
112 })
113 });
114}
115
116fn read_concurrent_contended(g: &mut BenchmarkGroup<WallTime>) {
117 let rt = tokio::runtime::Builder::new_current_thread()
118 .build()
119 .unwrap();
120
121 async fn task(lock: Arc<RwLock<()>>) {
122 let read = lock.read().await;
123 let _read = black_box(read);
124 }
125
126 let lock = Arc::new(RwLock::new(()));
127 g.bench_function("read_concurrent", |b| {
128 b.iter(|| {
129 let lock = lock.clone();
130 rt.block_on(async move {
131 let write = lock.write().await;
132 tokio::join! {
133 async move { drop(write) },
134 task(lock.clone()),
135 task(lock.clone()),
136 task(lock.clone()),
137 task(lock.clone()),
138 task(lock.clone()),
139 };
140 })
141 })
142 });
143}
144
145fn bench_contention(c: &mut Criterion) {
146 let mut group = c.benchmark_group("contention");
147 read_concurrent_contended(&mut group);
148 read_concurrent_contended_multi(&mut group);
149 group.finish();
150}
151
152fn bench_uncontented(c: &mut Criterion) {
153 let mut group = c.benchmark_group("uncontented");
154 read_uncontended(&mut group);
155 read_concurrent_uncontended(&mut group);
156 read_concurrent_uncontended_multi(&mut group);
157 group.finish();
158}
159
160criterion_group!(contention, bench_contention);
161criterion_group!(uncontented, bench_uncontented);
162
163criterion_main!(contention, uncontented);
164