1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 //! Benchmarks for the Rwlock.
15 //!
16 //! Designs of ylong_runtime benchmarks:
17 //! - Mainly follow designs of tokio rwlock tests.
18 //!
19 //! Designs of tokio benchmarks:
20 //! - Reference: [tokio/benches/sync_rwlock.rs](https://github.com/tokio-rs/tokio/blob/master/benches/sync_rwlock.rs)
21 
22 #![feature(test)]
23 
24 pub mod task_helpers;
25 
26 #[cfg(test)]
27 mod rwlock_bench {
28     extern crate test;
29 
30     use std::hint::black_box;
31     use std::sync::Arc;
32 
33     use test::Bencher;
34     use tokio::sync::RwLock;
35     use ylong_runtime::sync::rwlock::RwLock as YlongRwlock;
36 
37     pub use crate::task_helpers::{
38         tokio_runtime, tokio_rwlock_task, tokio_rwlock_write_task, ylong_rwlock_task,
39         ylong_rwlock_write_task,
40     };
41 
42     /// Benchmark test for tokio rwlock.
43     ///
44     /// # Brief
45     /// 1. Create a runtime with 6 threads.
46     /// 2. Create a rwLock variable.
47     /// 3. Concurrently read data for 6 times.
48     #[bench]
tokio_rwlock_read(b: &mut Bencher)49     fn tokio_rwlock_read(b: &mut Bencher) {
50         let rt = tokio_runtime();
51 
52         let lock = Arc::new(RwLock::new(()));
53         b.iter(black_box(|| {
54             let mut handlers = Vec::with_capacity(6);
55             for _ in 0..16 {
56                 let lock = lock.clone();
57                 handlers.push(rt.spawn(tokio_rwlock_task(lock.clone())));
58             }
59 
60             for handler in handlers {
61                 rt.block_on(handler).unwrap();
62             }
63         }));
64     }
65 
66     /// Benchmark test for ylong rwlock.
67     ///
68     /// # Brief
69     /// 1. Create a runtime with 6 threads.
70     /// 2. Create a rwLock variable.
71     /// 3. Concurrently read data for 6 times.
72     #[bench]
ylong_rwlock_read(b: &mut Bencher)73     fn ylong_rwlock_read(b: &mut Bencher) {
74         let handle = ylong_runtime::spawn(async move {});
75         let _ = ylong_runtime::block_on(handle);
76 
77         let lock = Arc::new(YlongRwlock::new(()));
78         b.iter(black_box(move || {
79             let mut handlers = Vec::with_capacity(6);
80             for _ in 0..16 {
81                 let lock = lock.clone();
82                 handlers.push(ylong_runtime::spawn(ylong_rwlock_task(lock.clone())));
83             }
84 
85             for handler in handlers {
86                 ylong_runtime::block_on(handler).unwrap();
87             }
88         }));
89     }
90 
91     /// Benchmark test for tokio rwlock.
92     ///
93     /// # Brief
94     /// 1. Create a runtime with 6 threads.
95     /// 2. Create a rwLock variable.
96     /// 3. Concurrently read data for 6 times.
97     #[bench]
tokio_rwlock_write(b: &mut Bencher)98     fn tokio_rwlock_write(b: &mut Bencher) {
99         let rt = tokio_runtime();
100 
101         let lock = Arc::new(RwLock::new(()));
102         b.iter(black_box(|| {
103             let mut handlers = Vec::with_capacity(6);
104             for _ in 0..16 {
105                 let lock = lock.clone();
106                 handlers.push(rt.spawn(tokio_rwlock_write_task(lock.clone())));
107             }
108 
109             for handler in handlers {
110                 rt.block_on(handler).unwrap();
111             }
112         }));
113     }
114 
115     /// Benchmark test for ylong rwlock.
116     ///
117     /// # Brief
118     /// 1. Create a runtime with 6 threads.
119     /// 2. Create a rwLock variable.
120     /// 3. Concurrently read data for 6 times.
121     #[bench]
ylong_rwlock_write(b: &mut Bencher)122     fn ylong_rwlock_write(b: &mut Bencher) {
123         let handle = ylong_runtime::spawn(async move {});
124         let _ = ylong_runtime::block_on(handle);
125 
126         let lock = Arc::new(YlongRwlock::new(()));
127         b.iter(black_box(move || {
128             let mut handlers = Vec::with_capacity(6);
129             for _ in 0..16 {
130                 let lock = lock.clone();
131                 handlers.push(ylong_runtime::spawn(ylong_rwlock_write_task(lock.clone())));
132             }
133 
134             for handler in handlers {
135                 ylong_runtime::block_on(handler).unwrap();
136             }
137         }));
138     }
139 
140     /// Benchmark test for tokio rwlock.
141     ///
142     /// # Brief
143     /// 1. Create a runtime with 6 threads.
144     /// 2. Create a rwLock variable.
145     /// 3. Write the rwlock
146     /// 4. Concurrently read data for 5 times.
147     #[bench]
tokio_rwlock_write_read(b: &mut Bencher)148     fn tokio_rwlock_write_read(b: &mut Bencher) {
149         let rt = tokio_runtime();
150 
151         let lock = Arc::new(RwLock::new(()));
152         b.iter(black_box(|| {
153             let _lock_in = lock.clone();
154             let mut handlers = Vec::with_capacity(12);
155 
156             for _ in 0..16 {
157                 let lock_in = lock.clone();
158                 handlers.push(rt.spawn(tokio_rwlock_write_task(lock_in)));
159             }
160 
161             for _ in 0..128 {
162                 let lock_in = lock.clone();
163                 handlers.push(rt.spawn(tokio_rwlock_task(lock_in)));
164             }
165             for handler in handlers {
166                 rt.block_on(handler).unwrap();
167             }
168         }));
169     }
170 
171     /// Benchmark test for ylong rwlock.
172     ///
173     /// # Brief
174     /// 1. Create a runtime with 6 threads.
175     /// 2. Create a rwLock variable.
176     /// 3. Write the rwlock
177     /// 4. Concurrently read data for 5 times.
178     #[bench]
ylong_rwlock_write_read(b: &mut Bencher)179     fn ylong_rwlock_write_read(b: &mut Bencher) {
180         let handle = ylong_runtime::spawn(async move {});
181         let _ = ylong_runtime::block_on(handle);
182 
183         let lock = Arc::new(YlongRwlock::new(()));
184         b.iter(black_box(|| {
185             let _lock_in = lock.clone();
186             let mut handlers = Vec::with_capacity(12);
187 
188             for _ in 0..16 {
189                 let lock_in = lock.clone();
190                 handlers.push(ylong_runtime::spawn(ylong_rwlock_write_task(lock_in)));
191             }
192 
193             for _ in 0..128 {
194                 let lock_in = lock.clone();
195                 handlers.push(ylong_runtime::spawn(ylong_rwlock_task(lock_in)));
196             }
197 
198             for handler in handlers {
199                 ylong_runtime::block_on(handler).unwrap();
200             }
201         }));
202     }
203 }
204