#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "std")]
mod tests;
#[cfg(feature = "std")]
pub use frame_benchmarking::Analysis;
pub use frame_benchmarking::{
benchmarking, BenchmarkBatch, BenchmarkParameter, BenchmarkResults, Benchmarking, BenchmarkingSetup,
BenchmarkingSetupInstance,
};
pub use paste;
#[doc(hidden)]
pub use sp_io::storage::root as storage_root;
pub use sp_runtime::traits::{Dispatchable, One, Zero};
#[macro_export]
macro_rules! runtime_benchmarks {
(
{ $runtime:ident, $pallet:ident }
_ {
$(
let $common:ident in $common_from:tt .. $common_to:expr => $common_instancer:expr;
)*
}
$( $rest:tt )*
) => {
$crate::benchmarks_iter!(
NO_INSTANCE
$runtime
$pallet
{ $( { $common , $common_from , $common_to , $common_instancer } )* }
( )
$( $rest )*
);
}
}
#[macro_export]
macro_rules! runtime_benchmarks_instance {
(
{ $runtime:ident, $pallet:ident, $instance:ident }
_ {
$(
let $common:ident in $common_from:tt .. $common_to:expr => $common_instancer:expr;
)*
}
$( $rest:tt )*
) => {
$crate::benchmarks_iter!(
$instance
$runtime
$pallet
{ $( { $common , $common_from , $common_to , $common_instancer } )* }
( )
$( $rest )*
);
}
}
#[macro_export]
#[allow(missing_docs)]
macro_rules! benchmarks_iter {
(
$instance:ident
$runtime:ident
$pallet:ident
{ $( $common:tt )* }
( $( $names:ident )* )
$name:ident { $( $code:tt )* }: _ ( $origin:expr $( , $arg:expr )* )
verify $postcode:block
$( $rest:tt )*
) => {
$crate::benchmarks_iter! {
$instance
$runtime
$pallet
{ $( $common )* }
( $( $names )* )
$name { $( $code )* }: $name ( $origin $( , $arg )* )
verify $postcode
$( $rest )*
}
};
(
NO_INSTANCE
$runtime:ident
$pallet:ident
{ $( $common:tt )* }
( $( $names:ident )* )
$name:ident { $( $code:tt )* }: $dispatch:ident ( $origin:expr $( , $arg:expr )* )
verify $postcode:block
$( $rest:tt )*
) => {
$crate::benchmarks_iter! {
NO_INSTANCE
$runtime
$pallet
{ $( $common )* }
( $( $names )* )
$name { $( $code )* }: {
<$pallet::Call<$runtime> as $crate::Dispatchable>::dispatch($pallet::Call::<$runtime>::$dispatch($($arg),*), $origin.into())?;
}
verify $postcode
$( $rest )*
}
};
(
$instance:ident
$runtime:ident
$pallet:ident
{ $( $common:tt )* }
( $( $names:ident )* )
$name:ident { $( $code:tt )* }: $dispatch:ident ( $origin:expr $( , $arg:expr )* )
verify $postcode:block
$( $rest:tt )*
) => {
$crate::benchmarks_iter! {
$instance
$runtime
$pallet
{ $( $common )* }
( $( $names )* )
$name { $( $code )* }: {
<$pallet::Call<$runtime, $instance> as $crate::Dispatchable>::dispatch($pallet::Call::<$runtime, $instance>::$dispatch($($arg),*), $origin.into())?;
}
verify $postcode
$( $rest )*
}
};
(
$instance:ident
$runtime:ident
$pallet:ident
{ $( $common:tt )* }
( $( $names:ident )* )
$name:ident { $( $code:tt )* }: $eval:block
verify $postcode:block
$( $rest:tt )*
) => {
$crate::benchmark_backend! {
$instance
$runtime
$pallet
$name
{ $( $common )* }
{ }
{ $eval }
{ $( $code )* }
$postcode
}
$crate::benchmarks_iter!(
$instance
$runtime
$pallet
{ $( $common )* }
( $( $names )* $name )
$( $rest )*
);
};
( $instance:ident $runtime:ident $pallet:ident { $( $common:tt )* } ( $( $names:ident )* ) ) => {
$crate::selected_benchmark!( $instance $runtime $pallet $( $names ),* );
$crate::impl_benchmark!( $instance $runtime $pallet $( $names ),* );
#[cfg(test)]
$crate::impl_benchmark_tests!( $instance $runtime $pallet $( $names ),* );
};
(
$instance:ident
$runtime:ident
$pallet:ident
{ $( $common:tt )* }
( $( $names:ident )* )
$name:ident { $( $code:tt )* }: _ ( $origin:expr $( , $arg:expr )* )
$( $rest:tt )*
) => {
$crate::benchmarks_iter! {
$instance
$runtime
$pallet
{ $( $common )* }
( $( $names )* )
$name { $( $code )* }: _ ( $origin $( , $arg )* )
verify { }
$( $rest )*
}
};
(
$instance:ident
$runtime:ident
$pallet:ident
{ $( $common:tt )* }
( $( $names:ident )* )
$name:ident { $( $code:tt )* }: $dispatch:ident ( $origin:expr $( , $arg:expr )* )
$( $rest:tt )*
) => {
$crate::benchmarks_iter! {
$instance
$runtime
$pallet
{ $( $common )* }
( $( $names )* )
$name { $( $code )* }: $dispatch ( $origin $( , $arg )* )
verify { }
$( $rest )*
}
};
(
$instance:ident
$runtime:ident
$pallet:ident
{ $( $common:tt )* }
( $( $names:ident )* )
$name:ident { $( $code:tt )* }: $eval:block
$( $rest:tt )*
) => {
$crate::benchmarks_iter!(
$instance
$runtime
$pallet
{ $( $common )* }
( $( $names )* )
$name { $( $code )* }: $eval
verify { }
$( $rest )*
);
};
}
#[macro_export]
#[allow(missing_docs)]
macro_rules! benchmark_backend {
($instance:ident $runtime:ident $pallet:ident $name:ident {
$( $common:tt )*
} {
$( PRE { $( $pre_parsed:tt )* } )*
} { $eval:block } {
let $pre_id:tt : $pre_ty:ty = $pre_ex:expr;
$( $rest:tt )*
} $postcode:block) => {
$crate::benchmark_backend! {
$instance $runtime $pallet $name { $( $common )* } {
$( PRE { $( $pre_parsed )* } )*
PRE { $pre_id , $pre_ty , $pre_ex }
} { $eval } { $( $rest )* } $postcode
}
};
($instance:ident $runtime:ident $pallet:ident $name:ident {
$( $common:tt )*
} {
$( $parsed:tt )*
} { $eval:block } {
let $param:ident in ( $param_from:expr ) .. $param_to:expr => $param_instancer:expr;
$( $rest:tt )*
} $postcode:block) => {
$crate::benchmark_backend! {
$instance $runtime $pallet $name { $( $common )* } {
$( $parsed )*
PARAM { $param , $param_from , $param_to , $param_instancer }
} { $eval } { $( $rest )* } $postcode
}
};
($instance:ident $runtime:ident $pallet:ident $name:ident {
$( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )*
} {
$( $parsed:tt )*
} { $eval:block } {
let $param:ident in ...;
$( $rest:tt )*
} $postcode:block) => {
$crate::benchmark_backend! {
$instance $runtime $pallet $name {
$( { $common , $common_from , $common_to , $common_instancer } )*
} {
$( $parsed )*
} { $eval } {
let $param
in ({ $( let $common = $common_from; )* $param })
.. ({ $( let $common = $common_to; )* $param })
=> ({ $( let $common = || -> Result<(), &'static str> { $common_instancer ; Ok(()) }; )* $param()? });
$( $rest )*
} $postcode
}
};
($instance:ident $runtime:ident $pallet:ident $name:ident {
$( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )*
} {
$( $parsed:tt )*
} { $eval:block } {
let $param:ident in _ .. _ => $param_instancer:expr ;
$( $rest:tt )*
} $postcode:block) => {
$crate::benchmark_backend! {
$instance $runtime $pallet $name {
$( { $common , $common_from , $common_to , $common_instancer } )*
} {
$( $parsed )*
} { $eval } {
let $param
in ({ $( let $common = $common_from; )* $param })
.. ({ $( let $common = $common_to; )* $param })
=> $param_instancer ;
$( $rest )*
} $postcode
}
};
($instance:ident $runtime:ident $pallet:ident $name:ident {
$( $common:tt )*
} {
$( $parsed:tt )*
} { $eval:block } {
let $param:ident in $param_from:tt .. $param_to:expr => $param_instancer:expr ;
$( $rest:tt )*
} $postcode:block) => {
$crate::benchmark_backend! {
$instance $runtime $pallet $name { $( $common )* } { $( $parsed )* } { $eval } {
let $param in ( $param_from ) .. $param_to => $param_instancer;
$( $rest )*
} $postcode
}
};
($instance:ident $runtime:ident $pallet:ident $name:ident {
$( $common:tt )*
} {
$( $parsed:tt )*
} { $eval:block } {
let $param:ident in $param_from:tt .. $param_to:expr;
$( $rest:tt )*
} $postcode:block) => {
$crate::benchmark_backend! {
$instance $runtime $pallet $name { $( $common )* } { $( $parsed )* } { $eval } {
let $param in $param_from .. $param_to => ();
$( $rest )*
} $postcode
}
};
($instance:ident $runtime:ident $pallet:ident $name:ident {
$( $common:tt )*
} {
$( $parsed:tt )*
} { $eval:block } {
let $pre_id:tt = $pre_ex:expr;
$( $rest:tt )*
} $postcode:block) => {
$crate::benchmark_backend! {
$instance $runtime $pallet $name { $( $common )* } { $( $parsed )* } { $eval } {
let $pre_id : _ = $pre_ex;
$( $rest )*
} $postcode
}
};
(NO_INSTANCE $runtime:ident $pallet:ident $name:ident {
$( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )*
} {
$( PRE { $pre_id:tt , $pre_ty:ty , $pre_ex:expr } )*
$( PARAM { $param:ident , $param_from:expr , $param_to:expr , $param_instancer:expr } )*
} { $eval:block } { $( $post:tt )* } $postcode:block) => {
#[allow(non_camel_case_types)]
struct $name;
#[allow(unused_variables)]
impl $crate::BenchmarkingSetup<$runtime> for $name {
fn components(&self) -> Vec<($crate::BenchmarkParameter, u32, u32)> {
vec! [
$(
($crate::BenchmarkParameter::$param, $param_from, $param_to)
),*
]
}
fn instance(&self, components: &[($crate::BenchmarkParameter, u32)])
-> Result<Box<dyn FnOnce() -> Result<(), &'static str>>, &'static str>
{
$(
let $common = $common_from;
)*
$(
let $param = components.iter().find(|&c| c.0 == $crate::BenchmarkParameter::$param).unwrap().1;
)*
$(
let $pre_id : $pre_ty = $pre_ex;
)*
$( $param_instancer ; )*
$( $post )*
Ok(Box::new(move || -> Result<(), &'static str> { $eval; Ok(()) }))
}
fn verify(&self, components: &[($crate::BenchmarkParameter, u32)])
-> Result<Box<dyn FnOnce() -> Result<(), &'static str>>, &'static str>
{
$(
let $common = $common_from;
)*
$(
let $param = components.iter().find(|&c| c.0 == $crate::BenchmarkParameter::$param).unwrap().1;
)*
$(
let $pre_id : $pre_ty = $pre_ex;
)*
$( $param_instancer ; )*
$( $post )*
Ok(Box::new(move || -> Result<(), &'static str> { $eval; $postcode; Ok(()) }))
}
}
};
($instance:ident $runtime:ident $pallet:ident $name:ident {
$( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )*
} {
$( PRE { $pre_id:tt , $pre_ty:ty , $pre_ex:expr } )*
$( PARAM { $param:ident , $param_from:expr , $param_to:expr , $param_instancer:expr } )*
} { $eval:block } { $( $post:tt )* } $postcode:block) => {
#[allow(non_camel_case_types)]
struct $name;
#[allow(unused_variables)]
impl $crate::BenchmarkingSetupInstance<$runtime, $instance> for $name {
fn components(&self) -> Vec<($crate::BenchmarkParameter, u32, u32)> {
vec! [
$(
($crate::BenchmarkParameter::$param, $param_from, $param_to)
),*
]
}
fn instance(&self, components: &[($crate::BenchmarkParameter, u32)])
-> Result<Box<dyn FnOnce() -> Result<(), &'static str>>, &'static str>
{
$(
let $common = $common_from;
)*
$(
let $param = components.iter().find(|&c| c.0 == $crate::BenchmarkParameter::$param).unwrap().1;
)*
$(
let $pre_id : $pre_ty = $pre_ex;
)*
$( $param_instancer ; )*
$( $post )*
Ok(Box::new(move || -> Result<(), &'static str> { $eval; Ok(()) }))
}
fn verify(&self, components: &[($crate::BenchmarkParameter, u32)])
-> Result<Box<dyn FnOnce() -> Result<(), &'static str>>, &'static str>
{
$(
let $common = $common_from;
)*
$(
let $param = components.iter().find(|&c| c.0 == $crate::BenchmarkParameter::$param).unwrap().1;
)*
$(
let $pre_id : $pre_ty = $pre_ex;
)*
$( $param_instancer ; )*
$( $post )*
Ok(Box::new(move || -> Result<(), &'static str> { $eval; $postcode; Ok(()) }))
}
}
}
}
#[macro_export]
macro_rules! selected_benchmark {
(
NO_INSTANCE $runtime:ident $pallet:ident $( $bench:ident ),*
) => {
#[allow(non_camel_case_types)]
enum SelectedBenchmark {
$( $bench, )*
}
impl $crate::BenchmarkingSetup<$runtime> for SelectedBenchmark {
fn components(&self) -> Vec<($crate::BenchmarkParameter, u32, u32)> {
match self {
$( Self::$bench => <$bench as $crate::BenchmarkingSetup<$runtime>>::components(&$bench), )*
}
}
fn instance(&self, components: &[($crate::BenchmarkParameter, u32)])
-> Result<Box<dyn FnOnce() -> Result<(), &'static str>>, &'static str>
{
match self {
$( Self::$bench => <$bench as $crate::BenchmarkingSetup<$runtime>>::instance(&$bench, components), )*
}
}
fn verify(&self, components: &[($crate::BenchmarkParameter, u32)])
-> Result<Box<dyn FnOnce() -> Result<(), &'static str>>, &'static str>
{
match self {
$( Self::$bench => <$bench as $crate::BenchmarkingSetup<$runtime>>::verify(&$bench, components), )*
}
}
}
};
(
$instance:ident $runtime:ident $pallet:ident $( $bench:ident ),*
) => {
#[allow(non_camel_case_types)]
enum SelectedBenchmark {
$( $bench, )*
}
impl $crate::BenchmarkingSetupInstance<$runtime, $instance> for SelectedBenchmark {
fn components(&self) -> Vec<($crate::BenchmarkParameter, u32, u32)> {
match self {
$( Self::$bench => <$bench as $crate::BenchmarkingSetupInstance<$runtime, $instance>>::components(&$bench), )*
}
}
fn instance(&self, components: &[($crate::BenchmarkParameter, u32)])
-> Result<Box<dyn FnOnce() -> Result<(), &'static str>>, &'static str>
{
match self {
$( Self::$bench => <$bench as $crate::BenchmarkingSetupInstance<$runtime, $instance>>::instance(&$bench, components), )*
}
}
fn verify(&self, components: &[($crate::BenchmarkParameter, u32)])
-> Result<Box<dyn FnOnce() -> Result<(), &'static str>>, &'static str>
{
match self {
$( Self::$bench => <$bench as $crate::BenchmarkingSetupInstance<$runtime, $instance>>::verify(&$bench, components), )*
}
}
}
}
}
#[macro_export]
macro_rules! impl_benchmark {
(
NO_INSTANCE $runtime:ident $pallet:ident $( $name:ident ),*
) => {
pub struct Benchmark;
impl $crate::Benchmarking<$crate::BenchmarkResults> for Benchmark {
fn benchmarks() -> Vec<&'static [u8]> {
vec![ $( stringify!($name).as_ref() ),* ]
}
fn run_benchmark(
extrinsic: &[u8],
lowest_range_values: &[u32],
highest_range_values: &[u32],
steps: &[u32],
repeat: u32,
) -> Result<Vec<$crate::BenchmarkResults>, &'static str> {
let extrinsic = sp_std::str::from_utf8(extrinsic)
.map_err(|_| "`extrinsic` is not a valid utf8 string!")?;
let selected_benchmark = match extrinsic {
$( stringify!($name) => SelectedBenchmark::$name, )*
_ => return Err("Could not find extrinsic."),
};
$crate::benchmarking::commit_db();
$crate::benchmarking::wipe_db();
let components = <SelectedBenchmark as $crate::BenchmarkingSetup<$runtime>>::components(&selected_benchmark);
let mut results: Vec<$crate::BenchmarkResults> = Vec::new();
let mut prev_steps = 10;
for (idx, (name, low, high)) in components.iter().enumerate() {
let steps = steps.get(idx).cloned().unwrap_or(prev_steps);
prev_steps = steps;
if steps == 0 { continue }
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;
let step_size = (diff / steps).max(1);
let num_of_steps = diff / step_size + 1;
for s in 0..num_of_steps {
let component_value = lowest + step_size * s;
let c: Vec<($crate::BenchmarkParameter, u32)> = components.iter()
.enumerate()
.map(|(idx, (n, _, h))|
if n == name {
(*n, component_value)
} else {
(*n, *highest_range_values.get(idx).unwrap_or(h))
}
)
.collect();
for _ in 0..repeat {
let closure_to_benchmark = <SelectedBenchmark as $crate::BenchmarkingSetup<$runtime>>::instance(&selected_benchmark, &c)?;
if $crate::Zero::is_zero(&frame_system::Module::<$runtime>::block_number()) {
frame_system::Module::<$runtime>::set_block_number(1u8.into());
}
$crate::benchmarking::commit_db();
frame_support::debug::trace!(target: "benchmark", "Start Benchmark: {:?} {:?}", name, component_value);
let start_extrinsic = $crate::benchmarking::current_time();
closure_to_benchmark()?;
let finish_extrinsic = $crate::benchmarking::current_time();
let elapsed_extrinsic = finish_extrinsic - start_extrinsic;
frame_support::debug::trace!(target: "benchmark", "End Benchmark: {} ns", elapsed_extrinsic);
let start_storage_root = $crate::benchmarking::current_time();
$crate::storage_root();
let finish_storage_root = $crate::benchmarking::current_time();
let elapsed_storage_root = finish_storage_root - start_storage_root;
results.push((c.clone(), elapsed_extrinsic, elapsed_storage_root));
$crate::benchmarking::wipe_db();
}
}
}
return Ok(results);
}
}
};
(
$instance:ident $runtime:ident $pallet:ident $( $name:ident ),*
) => {
pub struct Benchmark;
impl $crate::Benchmarking<$crate::BenchmarkResults> for Benchmark {
fn benchmarks() -> Vec<&'static [u8]> {
vec![ $( stringify!($name).as_ref() ),* ]
}
fn run_benchmark(
extrinsic: &[u8],
lowest_range_values: &[u32],
highest_range_values: &[u32],
steps: &[u32],
repeat: u32,
) -> Result<Vec<$crate::BenchmarkResults>, &'static str> {
let extrinsic = sp_std::str::from_utf8(extrinsic)
.map_err(|_| "`extrinsic` is not a valid utf8 string!")?;
let selected_benchmark = match extrinsic {
$( stringify!($name) => SelectedBenchmark::$name, )*
_ => return Err("Could not find extrinsic."),
};
$crate::benchmarking::commit_db();
$crate::benchmarking::wipe_db();
let components = <SelectedBenchmark as $crate::BenchmarkingSetupInstance<$runtime, $instance>>::components(&selected_benchmark);
let mut results: Vec<$crate::BenchmarkResults> = Vec::new();
let mut prev_steps = 10;
for (idx, (name, low, high)) in components.iter().enumerate() {
let steps = steps.get(idx).cloned().unwrap_or(prev_steps);
prev_steps = steps;
if steps == 0 { continue }
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;
let step_size = (diff / steps).max(1);
let num_of_steps = diff / step_size + 1;
for s in 0..num_of_steps {
let component_value = lowest + step_size * s;
let c: Vec<($crate::BenchmarkParameter, u32)> = components.iter()
.enumerate()
.map(|(idx, (n, _, h))|
if n == name {
(*n, component_value)
} else {
(*n, *highest_range_values.get(idx).unwrap_or(h))
}
)
.collect();
for _ in 0..repeat {
let closure_to_benchmark = <SelectedBenchmark as $crate::BenchmarkingSetupInstance<$runtime, $instance>>::instance(&selected_benchmark, &c)?;
if $crate::Zero::is_zero(&frame_system::Module::<$runtime>::block_number()) {
frame_system::Module::<$runtime>::set_block_number($crate::One::one());
}
$crate::benchmarking::commit_db();
frame_support::debug::trace!(target: "benchmark", "Start Benchmark: {:?} {:?}", name, component_value);
let start_extrinsic = $crate::benchmarking::current_time();
closure_to_benchmark()?;
let finish_extrinsic = $crate::benchmarking::current_time();
let elapsed_extrinsic = finish_extrinsic - start_extrinsic;
frame_support::debug::trace!(target: "benchmark", "End Benchmark: {} ns", elapsed_extrinsic);
let start_storage_root = $crate::benchmarking::current_time();
$crate::storage_root();
let finish_storage_root = $crate::benchmarking::current_time();
let elapsed_storage_root = finish_storage_root - start_storage_root;
results.push((c.clone(), elapsed_extrinsic, elapsed_storage_root));
$crate::benchmarking::wipe_db();
}
}
}
return Ok(results);
}
}
}
}
#[macro_export]
macro_rules! impl_benchmark_tests {
(
NO_INSTANCE
$runtime:ident
$pallet:ident
$( $name:ident ),*
) => {
$(
$crate::paste::item! {
fn [<test_benchmark_ $name>] () -> Result<(), &'static str>
{
let selected_benchmark = SelectedBenchmark::$name;
let components = <SelectedBenchmark as $crate::BenchmarkingSetup<$runtime>>::components(&selected_benchmark);
for (_, (name, low, high)) in components.iter().enumerate() {
for component_value in vec![low, high] {
let c: Vec<($crate::BenchmarkParameter, u32)> = components.iter()
.enumerate()
.map(|(_, (n, _, h))|
if n == name {
(*n, *component_value)
} else {
(*n, *h)
}
)
.collect();
let closure_to_verify = <SelectedBenchmark as $crate::BenchmarkingSetup<$runtime>>::verify(&selected_benchmark, &c)?;
if $crate::Zero::is_zero(&frame_system::Module::<$runtime>::block_number()) {
frame_system::Module::<$runtime>::set_block_number($crate::One::one());
}
closure_to_verify()?;
$crate::benchmarking::wipe_db();
}
}
Ok(())
}
}
)*
};
(
$instance:ident
$runtime:ident
$pallet:ident
$( $name:ident ),*
) => {
$(
$crate::paste::item! {
fn [<test_benchmark_ $name>] () -> Result<(), &'static str>
{
let selected_benchmark = SelectedBenchmark::$name;
let components = <SelectedBenchmark as $crate::BenchmarkingSetupInstance<$runtime, $instance>>::components(&selected_benchmark);
for (_, (name, low, high)) in components.iter().enumerate() {
for component_value in vec![low, high] {
let c: Vec<($crate::BenchmarkParameter, u32)> = components.iter()
.enumerate()
.map(|(_, (n, _, h))|
if n == name {
(*n, *component_value)
} else {
(*n, *h)
}
)
.collect();
let closure_to_verify = <SelectedBenchmark as $crate::BenchmarkingSetupInstance<$runtime, $instance>>::verify(&selected_benchmark, &c)?;
if $crate::Zero::is_zero(&frame_system::Module::<$runtime>::block_number()) {
frame_system::Module::<$runtime>::set_block_number($crate::One::one());
}
closure_to_verify()?;
$crate::benchmarking::wipe_db();
}
}
Ok(())
}
}
)*
};
}
#[macro_export]
macro_rules! add_benchmark {
( $params:ident, $batches:ident, $name:literal, $( $location:tt )* ) => (
let (pallet, benchmark, lowest_range_values, highest_range_values, steps, repeat) = $params;
if &pallet[..] == &$name[..] || &pallet[..] == &b"*"[..] {
if &pallet[..] == &b"*"[..] || &benchmark[..] == &b"*"[..] {
for benchmark in $( $location )*::Benchmark::benchmarks().into_iter() {
$batches.push($crate::BenchmarkBatch {
results: $( $location )*::Benchmark::run_benchmark(
benchmark,
&lowest_range_values[..],
&highest_range_values[..],
&steps[..],
repeat,
)?,
pallet: $name.to_vec(),
benchmark: benchmark.to_vec(),
});
}
} else {
$batches.push($crate::BenchmarkBatch {
results: $( $location )*::Benchmark::run_benchmark(
&benchmark[..],
&lowest_range_values[..],
&highest_range_values[..],
&steps[..],
repeat,
)?,
pallet: $name.to_vec(),
benchmark: benchmark.clone(),
});
}
}
)
}