12
12
// See the License for the specific language governing permissions and
13
13
// limitations under the License.
14
14
15
- use std:: io:: SeekFrom ;
16
-
17
15
use criterion:: BenchmarkId ;
18
16
use criterion:: Criterion ;
17
+ use futures:: future:: join_all;
19
18
use futures:: io;
20
19
use futures:: io:: BufReader ;
21
- use futures:: AsyncSeekExt ;
22
20
use opendal:: Operator ;
23
21
use opendal_test:: services:: fs;
24
22
use opendal_test:: services:: s3;
@@ -71,13 +69,15 @@ pub fn bench(c: &mut Criterion) {
71
69
. iter ( || bench_buf_read ( input. 0 . clone ( ) , input. 1 ) )
72
70
} ,
73
71
) ;
72
+
73
+ group. throughput ( criterion:: Throughput :: Bytes ( ( TOTAL_SIZE / 2 ) as u64 ) ) ;
74
74
group. bench_with_input (
75
- BenchmarkId :: new ( "seek_read " , & path) ,
75
+ BenchmarkId :: new ( "range_read " , & path) ,
76
76
& ( op. clone ( ) , & path) ,
77
77
|b, input| {
78
- let pos = rng. gen_range ( 0 ..TOTAL_SIZE - BATCH_SIZE ) as u64 ;
78
+ let pos = rng. gen_range ( 0 ..( TOTAL_SIZE / 2 ) as u64 ) as u64 ;
79
79
b. to_async ( & runtime)
80
- . iter ( || bench_seek_read ( input. 0 . clone ( ) , input. 1 , pos) )
80
+ . iter ( || bench_range_read ( input. 0 . clone ( ) , input. 1 , pos) )
81
81
} ,
82
82
) ;
83
83
group. throughput ( criterion:: Throughput :: Bytes ( ( TOTAL_SIZE / 2 ) as u64 ) ) ;
@@ -99,6 +99,40 @@ pub fn bench(c: &mut Criterion) {
99
99
. iter ( || bench_write ( input. 0 . clone ( ) , input. 1 , input. 2 . clone ( ) ) )
100
100
} ,
101
101
) ;
102
+
103
+ // runtime
104
+ const RUNTIME_THREAD : usize = 4 ;
105
+ let mut builder = tokio:: runtime:: Builder :: new_multi_thread ( ) ;
106
+ builder. enable_all ( ) . worker_threads ( RUNTIME_THREAD ) ;
107
+
108
+ let runtime = builder. build ( ) . unwrap ( ) ;
109
+ for parallel in [ 2 , 4 , 6 , 8 , 10 , 12 , 16 ] {
110
+ group. throughput ( criterion:: Throughput :: Bytes (
111
+ parallel as u64 * TOTAL_SIZE as u64 / 2 ,
112
+ ) ) ;
113
+ group. bench_with_input (
114
+ BenchmarkId :: new ( & format ! ( "parallel_read_{}" , parallel) , & path) ,
115
+ & ( op. clone ( ) , & path, content. clone ( ) ) ,
116
+ |b, input| {
117
+ let pos = rng. gen_range ( 0 ..( TOTAL_SIZE / 2 ) as u64 ) as u64 ;
118
+ b. to_async ( & runtime) . iter ( || {
119
+ let futures = ( 0 ..parallel)
120
+ . map ( |_| async {
121
+ bench_range_read ( input. 0 . clone ( ) , input. 1 , pos) . await ;
122
+ let mut d = 0 ;
123
+ // mock same little cpu work
124
+ for c in pos..pos + 100u64 {
125
+ d += c & 0x1f1f1f1f + c % 256 ;
126
+ }
127
+ let _ = d;
128
+ } )
129
+ . collect :: < Vec < _ > > ( ) ;
130
+ join_all ( futures)
131
+ } )
132
+ } ,
133
+ ) ;
134
+ }
135
+
102
136
group. finish ( ) ;
103
137
}
104
138
}
@@ -115,10 +149,8 @@ pub async fn bench_read(op: Operator, path: &str) {
115
149
io:: copy ( & mut r, & mut io:: sink ( ) ) . await . unwrap ( ) ;
116
150
}
117
151
118
- pub async fn bench_seek_read ( op : Operator , path : & str , pos : u64 ) {
119
- let mut r = op. object ( path) . limited_reader ( TOTAL_SIZE as u64 ) ;
120
- r. seek ( SeekFrom :: Start ( pos) ) . await . expect ( "seek" ) ;
121
- r. seek ( SeekFrom :: Start ( 0 ) ) . await . expect ( "seek" ) ;
152
+ pub async fn bench_range_read ( op : Operator , path : & str , pos : u64 ) {
153
+ let mut r = op. object ( path) . range_reader ( pos, ( TOTAL_SIZE / 2 ) as u64 ) ;
122
154
io:: copy ( & mut r, & mut io:: sink ( ) ) . await . unwrap ( ) ;
123
155
}
124
156
0 commit comments