benchmarks: Fix panic in case of a missing model (#7698)

Co-authored-by: Alexander Theißen <alex.theissen@me.com>
This commit is contained in:
Shawn Tabrizi
2020-12-08 20:00:52 -08:00
committed by GitHub
parent 9ce24fe1f4
commit 7a43cca875
3 changed files with 22 additions and 9 deletions
@@ -24,7 +24,7 @@ use std::path::PathBuf;
use serde::Serialize;
use crate::BenchmarkCmd;
use frame_benchmarking::{BenchmarkBatch, BenchmarkSelector, Analysis};
use frame_benchmarking::{BenchmarkBatch, BenchmarkSelector, Analysis, RegressionModel};
use sp_runtime::traits::Zero;
const VERSION: &'static str = env!("CARGO_PKG_VERSION");
@@ -134,6 +134,17 @@ fn map_results(batches: &[BenchmarkBatch]) -> Result<HashMap<String, Vec<Benchma
Ok(all_benchmarks)
}
// Get an iterator of errors from a model. If the model is `None` all errors are zero.
fn extract_errors(model: &Option<RegressionModel>) -> impl Iterator<Item=u128> + '_ {
let mut errors = model.as_ref().map(|m| m.se.regressor_values.iter());
std::iter::from_fn(move || {
match &mut errors {
Some(model) => model.next().map(|val| *val as u128),
_ => Some(0),
}
})
}
// Analyze and return the relevant results for a given benchmark.
fn get_benchmark_data(batch: &BenchmarkBatch) -> BenchmarkData {
// Analyze benchmarks to get the linear regression.
@@ -149,40 +160,40 @@ fn get_benchmark_data(batch: &BenchmarkBatch) -> BenchmarkData {
extrinsic_time.slopes.into_iter()
.zip(extrinsic_time.names.iter())
.zip(extrinsic_time.model.unwrap().se.regressor_values.iter())
.zip(extract_errors(&extrinsic_time.model))
.for_each(|((slope, name), error)| {
if !slope.is_zero() {
if !used_components.contains(&name) { used_components.push(name); }
used_extrinsic_time.push(ComponentSlope {
name: name.clone(),
slope: slope.saturating_mul(1000),
error: (*error as u128).saturating_mul(1000),
error: error.saturating_mul(1000),
});
}
});
reads.slopes.into_iter()
.zip(reads.names.iter())
.zip(reads.model.unwrap().se.regressor_values.iter())
.zip(extract_errors(&reads.model))
.for_each(|((slope, name), error)| {
if !slope.is_zero() {
if !used_components.contains(&name) { used_components.push(name); }
used_reads.push(ComponentSlope {
name: name.clone(),
slope,
error: *error as u128,
error,
});
}
});
writes.slopes.into_iter()
.zip(writes.names.iter())
.zip(writes.model.unwrap().se.regressor_values.iter())
.zip(extract_errors(&writes.model))
.for_each(|((slope, name), error)| {
if !slope.is_zero() {
if !used_components.contains(&name) { used_components.push(name); }
used_writes.push(ComponentSlope {
name: name.clone(),
slope,
error: *error as u128,
error,
});
}
});