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 async io operations. 15 //! 16 //! Designs of ylong_runtime benchmarks: 17 //! - Follow designs of tokio async io tests. 18 //! 19 //! Designs of tokio benchmarks: 20 //! - Reference: [tokio/benches/fs.rs](https://github.com/tokio-rs/tokio/blob/master/benches/fs.rs) 21 //! - Add new benchmarks to test write performance. 22 23 #![feature(test)] 24 #![cfg(unix)] 25 #![cfg(feature = "fs")] 26 27 pub mod task_helpers; 28 29 #[macro_export] 30 macro_rules! async_read { 31 ($runtime: ident) => { 32 #[bench] 33 fn async_read(b: &mut Bencher) { 34 let runtime = $runtime(); 35 36 b.iter(black_box(|| { 37 let task = || async { 38 let mut file = File::open(READ_FILE).await.unwrap(); 39 40 for _ in 0..TASK_NUM { 41 unsafe { 42 file.read_exact(&mut READ_BUFFER).await.unwrap(); 43 } 44 } 45 }; 46 47 runtime.block_on(task()); 48 })); 49 } 50 }; 51 } 52 53 #[macro_export] 54 macro_rules! async_read_by_chars { 55 ($runtime: ident) => { 56 #[bench] 57 fn async_read_by_chars(b: &mut Bencher) { 58 let runtime = $runtime(); 59 60 b.iter(black_box(|| { 61 let task = || async { 62 let mut file = File::open(READ_FILE).await.unwrap(); 63 let mut buffer = [0_u8]; 64 65 for i in 0..TASK_NUM { 66 unsafe { 67 file.read_exact(&mut buffer).await.unwrap(); 68 READ_BUFFER[i] = buffer[0]; 69 } 70 } 71 }; 72 73 runtime.block_on(task()); 74 })); 75 } 76 }; 77 } 78 79 #[macro_export] 80 macro_rules! async_write { 81 ($runtime: ident) => { 82 #[bench] 83 fn async_write(b: &mut Bencher) { 84 init_write_buffer(); 85 let runtime = $runtime(); 86 87 b.iter(black_box(|| { 88 let task = || async { 89 let mut file = File::create(WRITE_FILE).await.unwrap(); 90 for _ in 0..TASK_NUM { 91 unsafe { 92 let _ = file.write(&WRITE_BUFFER).await.unwrap(); 93 } 94 } 95 }; 96 97 runtime.block_on(task()); 98 })); 99 } 100 }; 101 } 102 103 #[cfg(test)] 104 mod ylong_async_file { 105 extern crate test; 106 use std::hint::black_box; 107 108 use test::Bencher; 109 use ylong_runtime::fs::File; 110 use ylong_runtime::io::{AsyncReadExt, AsyncWriteExt}; 111 112 use crate::task_helpers::*; 113 114 async_read!(ylong_runtime); 115 async_write!(ylong_runtime); 116 async_read_by_chars!(ylong_runtime); 117 } 118 119 #[cfg(test)] 120 mod tokio_async_file { 121 use tokio::fs::File; 122 use tokio::io::{AsyncReadExt, AsyncWriteExt}; 123 124 extern crate test; 125 use std::hint::black_box; 126 127 use test::Bencher; 128 129 use crate::task_helpers::*; 130 131 async_read!(tokio_runtime); 132 async_write!(tokio_runtime); 133 134 // For codec benchmarks, tokio has `async_read_codec` in `fs.rs`. That's the 135 // correct ways to use tokio's codec features. However, here, use the same 136 // benchmark to apply the same method to test ylong, tokio, swift, and avoid 137 // new packages imported. 138 async_read_by_chars!(tokio_runtime); 139 } 140