@@ -29,24 +29,40 @@ pub struct Analysis {
29
29
model : Option < RegressionModel > ,
30
30
}
31
31
32
+ pub enum BenchmarkSelector {
33
+ ExtrinsicTime ,
34
+ StorageRootTime ,
35
+ Reads ,
36
+ Writes ,
37
+ }
38
+
32
39
impl Analysis {
33
- pub fn median_slopes ( r : & Vec < BenchmarkResults > ) -> Option < Self > {
34
- let results = r[ 0 ] . 0 . iter ( ) . enumerate ( ) . map ( |( i, & ( param, _) ) | {
40
+ pub fn median_slopes ( r : & Vec < BenchmarkResults > , selector : BenchmarkSelector ) -> Option < Self > {
41
+ let results = r[ 0 ] . components . iter ( ) . enumerate ( ) . map ( |( i, & ( param, _) ) | {
35
42
let mut counted = BTreeMap :: < Vec < u32 > , usize > :: new ( ) ;
36
- for ( params , _ , _ ) in r. iter ( ) {
37
- let mut p = params . iter ( ) . map ( |x| x. 1 ) . collect :: < Vec < _ > > ( ) ;
43
+ for result in r. iter ( ) {
44
+ let mut p = result . components . iter ( ) . map ( |x| x. 1 ) . collect :: < Vec < _ > > ( ) ;
38
45
p[ i] = 0 ;
39
46
* counted. entry ( p) . or_default ( ) += 1 ;
40
47
}
41
48
let others: Vec < u32 > = counted. iter ( ) . max_by_key ( |i| i. 1 ) . expect ( "r is not empty; qed" ) . 0 . clone ( ) ;
42
49
let values = r. iter ( )
43
50
. filter ( |v|
44
- v. 0 . iter ( )
51
+ v. components . iter ( )
45
52
. map ( |x| x. 1 )
46
53
. zip ( others. iter ( ) )
47
54
. enumerate ( )
48
55
. all ( |( j, ( v1, v2) ) | j == i || v1 == * v2)
49
- ) . map ( |( ps, v, _) | ( ps[ i] . 1 , * v) )
56
+ ) . map ( |result| {
57
+ // Extract the data we are interested in analyzing
58
+ let data = match selector {
59
+ BenchmarkSelector :: ExtrinsicTime => result. extrinsic_time ,
60
+ BenchmarkSelector :: StorageRootTime => result. storage_root_time ,
61
+ BenchmarkSelector :: Reads => result. reads . into ( ) ,
62
+ BenchmarkSelector :: Writes => result. writes . into ( ) ,
63
+ } ;
64
+ ( result. components [ i] . 1 , data)
65
+ } )
50
66
. collect :: < Vec < _ > > ( ) ;
51
67
( format ! ( "{:?}" , param) , i, others, values)
52
68
} ) . collect :: < Vec < _ > > ( ) ;
@@ -97,12 +113,18 @@ impl Analysis {
97
113
} )
98
114
}
99
115
100
- pub fn min_squares_iqr ( r : & Vec < BenchmarkResults > ) -> Option < Self > {
116
+ pub fn min_squares_iqr ( r : & Vec < BenchmarkResults > , selector : BenchmarkSelector ) -> Option < Self > {
101
117
let mut results = BTreeMap :: < Vec < u32 > , Vec < u128 > > :: new ( ) ;
102
- for & ( ref params, t, _) in r. iter ( ) {
103
- let p = params. iter ( ) . map ( |x| x. 1 ) . collect :: < Vec < _ > > ( ) ;
104
- results. entry ( p) . or_default ( ) . push ( t) ;
118
+ for result in r. iter ( ) {
119
+ let p = result. components . iter ( ) . map ( |x| x. 1 ) . collect :: < Vec < _ > > ( ) ;
120
+ results. entry ( p) . or_default ( ) . push ( match selector {
121
+ BenchmarkSelector :: ExtrinsicTime => result. extrinsic_time ,
122
+ BenchmarkSelector :: StorageRootTime => result. storage_root_time ,
123
+ BenchmarkSelector :: Reads => result. reads . into ( ) ,
124
+ BenchmarkSelector :: Writes => result. writes . into ( ) ,
125
+ } )
105
126
}
127
+
106
128
for ( _, rs) in results. iter_mut ( ) {
107
129
rs. sort ( ) ;
108
130
let ql = rs. len ( ) / 4 ;
@@ -111,7 +133,7 @@ impl Analysis {
111
133
112
134
let mut data = vec ! [ ( "Y" , results. iter( ) . flat_map( |x| x. 1 . iter( ) . map( |v| * v as f64 ) ) . collect( ) ) ] ;
113
135
114
- let names = r[ 0 ] . 0 . iter ( ) . map ( |x| format ! ( "{:?}" , x. 0 ) ) . collect :: < Vec < _ > > ( ) ;
136
+ let names = r[ 0 ] . components . iter ( ) . map ( |x| format ! ( "{:?}" , x. 0 ) ) . collect :: < Vec < _ > > ( ) ;
115
137
data. extend ( names. iter ( )
116
138
. enumerate ( )
117
139
. map ( |( i, p) | (
@@ -217,40 +239,88 @@ impl std::fmt::Display for Analysis {
217
239
}
218
240
}
219
241
242
+ impl std:: fmt:: Debug for Analysis {
243
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
244
+ write ! ( f, "{}" , self . base) ?;
245
+ for ( & m, n) in self . slopes . iter ( ) . zip ( self . names . iter ( ) ) {
246
+ write ! ( f, " + ({} * {})" , m, n) ?;
247
+ }
248
+ write ! ( f, "" )
249
+ }
250
+ }
251
+
220
252
#[ cfg( test) ]
221
253
mod tests {
222
254
use super :: * ;
223
255
use crate :: BenchmarkParameter ;
224
256
257
+ fn benchmark_result (
258
+ components : Vec < ( BenchmarkParameter , u32 ) > ,
259
+ extrinsic_time : u128 ,
260
+ storage_root_time : u128 ,
261
+ reads : u32 ,
262
+ writes : u32 ,
263
+ ) -> BenchmarkResults {
264
+ BenchmarkResults {
265
+ components,
266
+ extrinsic_time,
267
+ storage_root_time,
268
+ reads,
269
+ repeat_reads : 0 ,
270
+ writes,
271
+ repeat_writes : 0 ,
272
+ }
273
+ }
274
+
225
275
#[ test]
226
276
fn analysis_median_slopes_should_work ( ) {
227
- let a = Analysis :: median_slopes ( & vec ! [
228
- ( vec![ ( BenchmarkParameter :: n, 1 ) , ( BenchmarkParameter :: m, 5 ) ] , 11_500_000 , 0 ) ,
229
- ( vec![ ( BenchmarkParameter :: n, 2 ) , ( BenchmarkParameter :: m, 5 ) ] , 12_500_000 , 0 ) ,
230
- ( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 5 ) ] , 13_500_000 , 0 ) ,
231
- ( vec![ ( BenchmarkParameter :: n, 4 ) , ( BenchmarkParameter :: m, 5 ) ] , 14_500_000 , 0 ) ,
232
- ( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 1 ) ] , 13_100_000 , 0 ) ,
233
- ( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 3 ) ] , 13_300_000 , 0 ) ,
234
- ( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 7 ) ] , 13_700_000 , 0 ) ,
235
- ( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 10 ) ] , 14_000_000 , 0 ) ,
236
- ] ) . unwrap ( ) ;
237
- assert_eq ! ( a. base, 10_000_000 ) ;
238
- assert_eq ! ( a. slopes, vec![ 1_000_000 , 100_000 ] ) ;
277
+ let data = vec ! [
278
+ benchmark_result( vec![ ( BenchmarkParameter :: n, 1 ) , ( BenchmarkParameter :: m, 5 ) ] , 11_500_000 , 0 , 3 , 10 ) ,
279
+ benchmark_result( vec![ ( BenchmarkParameter :: n, 2 ) , ( BenchmarkParameter :: m, 5 ) ] , 12_500_000 , 0 , 4 , 10 ) ,
280
+ benchmark_result( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 5 ) ] , 13_500_000 , 0 , 5 , 10 ) ,
281
+ benchmark_result( vec![ ( BenchmarkParameter :: n, 4 ) , ( BenchmarkParameter :: m, 5 ) ] , 14_500_000 , 0 , 6 , 10 ) ,
282
+ benchmark_result( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 1 ) ] , 13_100_000 , 0 , 5 , 2 ) ,
283
+ benchmark_result( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 3 ) ] , 13_300_000 , 0 , 5 , 6 ) ,
284
+ benchmark_result( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 7 ) ] , 13_700_000 , 0 , 5 , 14 ) ,
285
+ benchmark_result( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 10 ) ] , 14_000_000 , 0 , 5 , 20 ) ,
286
+ ] ;
287
+
288
+ let extrinsic_time = Analysis :: median_slopes ( & data, BenchmarkSelector :: ExtrinsicTime ) . unwrap ( ) ;
289
+ assert_eq ! ( extrinsic_time. base, 10_000_000 ) ;
290
+ assert_eq ! ( extrinsic_time. slopes, vec![ 1_000_000 , 100_000 ] ) ;
291
+
292
+ let reads = Analysis :: median_slopes ( & data, BenchmarkSelector :: Reads ) . unwrap ( ) ;
293
+ assert_eq ! ( reads. base, 2 ) ;
294
+ assert_eq ! ( reads. slopes, vec![ 1 , 0 ] ) ;
295
+
296
+ let writes = Analysis :: median_slopes ( & data, BenchmarkSelector :: Writes ) . unwrap ( ) ;
297
+ assert_eq ! ( writes. base, 0 ) ;
298
+ assert_eq ! ( writes. slopes, vec![ 0 , 2 ] ) ;
239
299
}
240
300
241
301
#[ test]
242
302
fn analysis_median_min_squares_should_work ( ) {
243
- let a = Analysis :: min_squares_iqr ( & vec ! [
244
- ( vec![ ( BenchmarkParameter :: n, 1 ) , ( BenchmarkParameter :: m, 5 ) ] , 11_500_000 , 0 ) ,
245
- ( vec![ ( BenchmarkParameter :: n, 2 ) , ( BenchmarkParameter :: m, 5 ) ] , 12_500_000 , 0 ) ,
246
- ( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 5 ) ] , 13_500_000 , 0 ) ,
247
- ( vec![ ( BenchmarkParameter :: n, 4 ) , ( BenchmarkParameter :: m, 5 ) ] , 14_500_000 , 0 ) ,
248
- ( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 1 ) ] , 13_100_000 , 0 ) ,
249
- ( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 3 ) ] , 13_300_000 , 0 ) ,
250
- ( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 7 ) ] , 13_700_000 , 0 ) ,
251
- ( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 10 ) ] , 14_000_000 , 0 ) ,
252
- ] ) . unwrap ( ) ;
253
- assert_eq ! ( a. base, 10_000_000 ) ;
254
- assert_eq ! ( a. slopes, vec![ 1_000_000 , 100_000 ] ) ;
303
+ let data = vec ! [
304
+ benchmark_result( vec![ ( BenchmarkParameter :: n, 1 ) , ( BenchmarkParameter :: m, 5 ) ] , 11_500_000 , 0 , 3 , 10 ) ,
305
+ benchmark_result( vec![ ( BenchmarkParameter :: n, 2 ) , ( BenchmarkParameter :: m, 5 ) ] , 12_500_000 , 0 , 4 , 10 ) ,
306
+ benchmark_result( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 5 ) ] , 13_500_000 , 0 , 5 , 10 ) ,
307
+ benchmark_result( vec![ ( BenchmarkParameter :: n, 4 ) , ( BenchmarkParameter :: m, 5 ) ] , 14_500_000 , 0 , 6 , 10 ) ,
308
+ benchmark_result( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 1 ) ] , 13_100_000 , 0 , 5 , 2 ) ,
309
+ benchmark_result( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 3 ) ] , 13_300_000 , 0 , 5 , 6 ) ,
310
+ benchmark_result( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 7 ) ] , 13_700_000 , 0 , 5 , 14 ) ,
311
+ benchmark_result( vec![ ( BenchmarkParameter :: n, 3 ) , ( BenchmarkParameter :: m, 10 ) ] , 14_000_000 , 0 , 5 , 20 ) ,
312
+ ] ;
313
+
314
+ let extrinsic_time = Analysis :: min_squares_iqr ( & data, BenchmarkSelector :: ExtrinsicTime ) . unwrap ( ) ;
315
+ assert_eq ! ( extrinsic_time. base, 10_000_000 ) ;
316
+ assert_eq ! ( extrinsic_time. slopes, vec![ 1_000_000 , 100_000 ] ) ;
317
+
318
+ let reads = Analysis :: min_squares_iqr ( & data, BenchmarkSelector :: Reads ) . unwrap ( ) ;
319
+ assert_eq ! ( reads. base, 2 ) ;
320
+ assert_eq ! ( reads. slopes, vec![ 1 , 0 ] ) ;
321
+
322
+ let writes = Analysis :: min_squares_iqr ( & data, BenchmarkSelector :: Writes ) . unwrap ( ) ;
323
+ assert_eq ! ( writes. base, 0 ) ;
324
+ assert_eq ! ( writes. slopes, vec![ 0 , 2 ] ) ;
255
325
}
256
326
}
0 commit comments