diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 9e4496f1e9d9e..ae8251f620966 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -820,15 +820,35 @@ impl_runtime_apis! { fn dispatch_benchmark( module: Vec, extrinsic: Vec, + lowest_range_values: Vec, + highest_range_values: Vec, steps: Vec, repeat: u32, ) -> Result, RuntimeString> { use frame_benchmarking::Benchmarking; let result = match module.as_slice() { - b"pallet-balances" | b"balances" => Balances::run_benchmark(extrinsic, steps, repeat), - b"pallet-identity" | b"identity" => Identity::run_benchmark(extrinsic, steps, repeat), - b"pallet-timestamp" | b"timestamp" => Timestamp::run_benchmark(extrinsic, steps, repeat), + b"pallet-balances" | b"balances" => Balances::run_benchmark( + extrinsic, + lowest_range_values, + highest_range_values, + steps, + repeat, + ), + b"pallet-identity" | b"identity" => Identity::run_benchmark( + extrinsic, + lowest_range_values, + highest_range_values, + steps, + repeat, + ), + b"pallet-timestamp" | b"timestamp" => Timestamp::run_benchmark( + extrinsic, + lowest_range_values, + highest_range_values, + steps, + repeat, + ), _ => Err("Benchmark not found for this pallet."), }; diff --git a/frame/benchmarking/src/lib.rs b/frame/benchmarking/src/lib.rs index e6b6a4f3f59ec..d979000432c91 100644 --- a/frame/benchmarking/src/lib.rs +++ b/frame/benchmarking/src/lib.rs @@ -140,7 +140,13 @@ macro_rules! impl_benchmark { $( $name:ident ),* ) => { impl $crate::Benchmarking<$crate::BenchmarkResults> for Module { - fn run_benchmark(extrinsic: Vec, steps: Vec, repeat: u32) -> Result, &'static str> { + fn run_benchmark( + extrinsic: Vec, + lowest_range_values: Vec, + highest_range_values: Vec, + steps: Vec, + repeat: u32, + ) -> Result, &'static str> { // Map the input to the selected benchmark. let extrinsic = sp_std::str::from_utf8(extrinsic.as_slice()) .map_err(|_| "Could not find extrinsic")?; @@ -157,26 +163,38 @@ macro_rules! impl_benchmark { let mut results: Vec<$crate::BenchmarkResults> = Vec::new(); // Default number of steps for a component. - let mut prev_steps = &10; + let mut prev_steps = 10; // Select the component we will be benchmarking. Each component will be benchmarked. for (idx, (name, low, high)) in components.iter().enumerate() { // Get the number of steps for this component. - let steps = steps.get(idx).unwrap_or(&prev_steps); + let steps = steps.get(idx).cloned().unwrap_or(prev_steps); prev_steps = steps; + let lowest = lowest_range_values.get(idx).cloned().unwrap_or(*low); + let highest = highest_range_values.get(idx).cloned().unwrap_or(*high); + + let diff = highest - lowest; + // Create up to `STEPS` steps for that component between high and low. - let step_size = ((high - low) / steps).max(1); - let num_of_steps = (high - low) / step_size + 1; + let step_size = (diff / steps).max(1); + let num_of_steps = diff / step_size + 1; + for s in 0..num_of_steps { // This is the value we will be testing for component `name` - let component_value = low + step_size * s; + let component_value = lowest + step_size * s; - // Select the mid value for all the other components. + // Select the max value for all the other components. let c: Vec<($crate::BenchmarkParameter, u32)> = components.iter() - .map(|(n, l, h)| - (*n, if n == name { component_value } else { *h }) - ).collect(); + .enumerate() + .map(|(idx, (n, l, h))| + if n == name { + (*n, component_value) + } else { + (*n, *highest_range_values.get(idx).unwrap_or(h)) + } + ) + .collect(); // Run the benchmark `repeat` times. for _ in 0..repeat { diff --git a/frame/benchmarking/src/utils.rs b/frame/benchmarking/src/utils.rs index f9d1ecf8cd322..87996c3f57400 100644 --- a/frame/benchmarking/src/utils.rs +++ b/frame/benchmarking/src/utils.rs @@ -41,6 +41,8 @@ sp_api::decl_runtime_apis! { fn dispatch_benchmark( module: Vec, extrinsic: Vec, + lowest_range_values: Vec, + highest_range_values: Vec, steps: Vec, repeat: u32, ) -> Result, RuntimeString>; @@ -78,8 +80,16 @@ pub trait Benchmarking { /// Parameters /// - `extrinsic`: The name of extrinsic function you want to benchmark encoded as bytes. /// - `steps`: The number of sample points you want to take across the range of parameters. + /// - `lowest_range_values`: The lowest number for each range of parameters. + /// - `highest_range_values`: The highest number for each range of parameters. /// - `repeat`: The number of times you want to repeat a benchmark. - fn run_benchmark(extrinsic: Vec, steps: Vec, repeat: u32) -> Result, &'static str>; + fn run_benchmark( + extrinsic: Vec, + lowest_range_values: Vec, + highest_range_values: Vec, + steps: Vec, + repeat: u32, + ) -> Result, &'static str>; } /// The required setup for creating a benchmark. diff --git a/utils/frame/benchmarking-cli/src/lib.rs b/utils/frame/benchmarking-cli/src/lib.rs index b09b1bad62781..899419e5de5ad 100644 --- a/utils/frame/benchmarking-cli/src/lib.rs +++ b/utils/frame/benchmarking-cli/src/lib.rs @@ -39,6 +39,14 @@ pub struct BenchmarkCmd { #[structopt(short, long, use_delimiter = true)] pub steps: Vec, + /// Indicates lowest values for each of the component ranges. + #[structopt(long, use_delimiter = true)] + pub lowest_range_values: Vec, + + /// Indicates highest values for each of the component ranges. + #[structopt(long, use_delimiter = true)] + pub highest_range_values: Vec, + /// Select how many repetitions of this benchmark should run. #[structopt(short, long, default_value = "1")] pub repeat: u32, @@ -104,7 +112,14 @@ impl BenchmarkCmd { &mut changes, &executor, "Benchmark_dispatch_benchmark", - &(&self.pallet, &self.extrinsic, self.steps.clone(), self.repeat).encode(), + &( + &self.pallet, + &self.extrinsic, + self.lowest_range_values.clone(), + self.highest_range_values.clone(), + self.steps.clone(), + self.repeat, + ).encode(), Default::default(), ) .execute(strategy.into()) @@ -117,9 +132,11 @@ impl BenchmarkCmd { Ok(results) => { // Print benchmark metadata println!( - "Pallet: {:?}, Extrinsic: {:?}, Steps: {:?}, Repeat: {:?}", + "Pallet: {:?}, Extrinsic: {:?}, Lowest values: {:?}, Highest values: {:?}, Steps: {:?}, Repeat: {:?}", self.pallet, self.extrinsic, + self.lowest_range_values, + self.highest_range_values, self.steps, self.repeat, );