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