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