mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 04:01:10 +00:00
FRAME Weights with Storage Metadata (#9471)
* weights with metadata * fix * fix contract test * skip metadata tag * special handling for `frame_system` * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=frame_system --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/system/src/weights.rs --template=./.maintain/frame-weight-template.hbs * add skip metadata to contracts * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_contracts --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/contracts/src/weights.rs --template=./.maintain/frame-weight-template.hbs * fix contract test * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_democracy --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/democracy/src/weights.rs --template=./.maintain/frame-weight-template.hbs * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_bounties --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/bounties/src/weights.rs --template=./.maintain/frame-weight-template.hbs * expose component information * fix test generation * refactor list benchmarks * move component selection out of runtime * add benchmark verification * missing feature * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_bounties --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/bounties/src/weights.rs --template=./.maintain/frame-weight-template.hbs * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_democracy --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/democracy/src/weights.rs --template=./.maintain/frame-weight-template.hbs * add internal repeats * update weights with internal repeats * fix warning * return error with pov * try without tracking * Revert "return error with pov" This reverts commit 44c36cbbd3c6818f36f377e3e291f1df156e40f7. * Revert "try without tracking" This reverts commit f401c44aebff2232389d8d307b20924891e5d77d. * Revert "Revert "try without tracking"" This reverts commit 4b4e05929802ad3e8154e107359447634e5fb21b. * state without tracking * fix build * temp test * split db and timing benchmarks * extend db results? * default repeat is internal * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_democracy --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/democracy/src/weights.rs --template=./.maintain/frame-weight-template.hbs * fix warning * bump linked hash map * use linked hash map for storage tracker * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_democracy --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/democracy/src/weights.rs --template=./.maintain/frame-weight-template.hbs * remove conflicting short command * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_democracy --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/democracy/src/weights.rs --template=./.maintain/frame-weight-template.hbs * missed one linked hashmap * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_bounties --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/bounties/src/weights.rs --template=./.maintain/frame-weight-template.hbs * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_bounties --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/bounties/src/weights.rs --template=./.maintain/frame-weight-template.hbs * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_election_provider_multi_phase --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/election-provider-multi-phase/src/weights.rs --template=./.maintain/frame-weight-template.hbs * new weights with latest changes * Update frame/benchmarking/src/utils.rs Co-authored-by: Parity Benchmarking Bot <admin@parity.io>
This commit is contained in:
@@ -190,6 +190,7 @@ macro_rules! benchmarks {
|
||||
{ }
|
||||
( )
|
||||
( )
|
||||
( )
|
||||
$( $rest )*
|
||||
);
|
||||
}
|
||||
@@ -208,6 +209,7 @@ macro_rules! benchmarks_instance {
|
||||
{ }
|
||||
( )
|
||||
( )
|
||||
( )
|
||||
$( $rest )*
|
||||
);
|
||||
}
|
||||
@@ -226,6 +228,7 @@ macro_rules! benchmarks_instance_pallet {
|
||||
{ }
|
||||
( )
|
||||
( )
|
||||
( )
|
||||
$( $rest )*
|
||||
);
|
||||
}
|
||||
@@ -240,6 +243,7 @@ macro_rules! benchmarks_iter {
|
||||
{ $( $where_clause:tt )* }
|
||||
( $( $names:tt )* )
|
||||
( $( $names_extra:tt )* )
|
||||
( $( $names_skip_meta:tt )* )
|
||||
where_clause { where $( $where_bound:tt )* }
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
@@ -248,15 +252,38 @@ macro_rules! benchmarks_iter {
|
||||
{ $( $where_bound )* }
|
||||
( $( $names )* )
|
||||
( $( $names_extra )* )
|
||||
( $( $names_skip_meta )* )
|
||||
$( $rest )*
|
||||
}
|
||||
};
|
||||
// detect and extract extra tag:
|
||||
// detect and extract `#[skip_meta]` tag:
|
||||
(
|
||||
{ $( $instance:ident: $instance_bound:tt )? }
|
||||
{ $( $where_clause:tt )* }
|
||||
( $( $names:tt )* )
|
||||
( $( $names_extra:tt )* )
|
||||
( $( $names_skip_meta:tt )* )
|
||||
#[skip_meta]
|
||||
$name:ident
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
$crate::benchmarks_iter! {
|
||||
{ $( $instance: $instance_bound )? }
|
||||
{ $( $where_clause )* }
|
||||
( $( $names )* )
|
||||
( $( $names_extra )* )
|
||||
( $( $names_skip_meta )* $name )
|
||||
$name
|
||||
$( $rest )*
|
||||
}
|
||||
};
|
||||
// detect and extract `#[extra] tag:
|
||||
(
|
||||
{ $( $instance:ident: $instance_bound:tt )? }
|
||||
{ $( $where_clause:tt )* }
|
||||
( $( $names:tt )* )
|
||||
( $( $names_extra:tt )* )
|
||||
( $( $names_skip_meta:tt )* )
|
||||
#[extra]
|
||||
$name:ident
|
||||
$( $rest:tt )*
|
||||
@@ -266,6 +293,7 @@ macro_rules! benchmarks_iter {
|
||||
{ $( $where_clause )* }
|
||||
( $( $names )* )
|
||||
( $( $names_extra )* $name )
|
||||
( $( $names_skip_meta )* )
|
||||
$name
|
||||
$( $rest )*
|
||||
}
|
||||
@@ -276,6 +304,7 @@ macro_rules! benchmarks_iter {
|
||||
{ $( $where_clause:tt )* }
|
||||
( $( $names:tt )* ) // This contains $( $( { $instance } )? $name:ident )*
|
||||
( $( $names_extra:tt )* )
|
||||
( $( $names_skip_meta:tt )* )
|
||||
$name:ident { $( $code:tt )* }: _ ( $origin:expr $( , $arg:expr )* )
|
||||
verify $postcode:block
|
||||
$( $rest:tt )*
|
||||
@@ -285,6 +314,7 @@ macro_rules! benchmarks_iter {
|
||||
{ $( $where_clause )* }
|
||||
( $( $names )* )
|
||||
( $( $names_extra )* )
|
||||
( $( $names_skip_meta )* )
|
||||
$name { $( $code )* }: $name ( $origin $( , $arg )* )
|
||||
verify $postcode
|
||||
$( $rest )*
|
||||
@@ -296,6 +326,7 @@ macro_rules! benchmarks_iter {
|
||||
{ $( $where_clause:tt )* }
|
||||
( $( $names:tt )* )
|
||||
( $( $names_extra:tt )* )
|
||||
( $( $names_skip_meta:tt )* )
|
||||
$name:ident { $( $code:tt )* }: $dispatch:ident ( $origin:expr $( , $arg:expr )* )
|
||||
verify $postcode:block
|
||||
$( $rest:tt )*
|
||||
@@ -305,6 +336,7 @@ macro_rules! benchmarks_iter {
|
||||
{ $( $where_clause )* }
|
||||
( $( $names )* )
|
||||
( $( $names_extra )* )
|
||||
( $( $names_skip_meta )* )
|
||||
$name {
|
||||
$( $code )*
|
||||
let __benchmarked_call_encoded = $crate::frame_support::codec::Encode::encode(
|
||||
@@ -331,6 +363,7 @@ macro_rules! benchmarks_iter {
|
||||
{ $( $where_clause:tt )* }
|
||||
( $( $names:tt )* )
|
||||
( $( $names_extra:tt )* )
|
||||
( $( $names_skip_meta:tt )* )
|
||||
$name:ident { $( $code:tt )* }: $eval:block
|
||||
verify $postcode:block
|
||||
$( $rest:tt )*
|
||||
@@ -357,6 +390,7 @@ macro_rules! benchmarks_iter {
|
||||
{ $( $where_clause )* }
|
||||
( $( $names )* { $( $instance )? } $name )
|
||||
( $( $names_extra )* )
|
||||
( $( $names_skip_meta )* )
|
||||
$( $rest )*
|
||||
);
|
||||
};
|
||||
@@ -366,6 +400,7 @@ macro_rules! benchmarks_iter {
|
||||
{ $( $where_clause:tt )* }
|
||||
( $( $names:tt )* )
|
||||
( $( $names_extra:tt )* )
|
||||
( $( $names_skip_meta:tt )* )
|
||||
) => {
|
||||
$crate::selected_benchmark!(
|
||||
{ $( $where_clause)* }
|
||||
@@ -377,6 +412,7 @@ macro_rules! benchmarks_iter {
|
||||
{ $( $instance: $instance_bound )? }
|
||||
( $( $names )* )
|
||||
( $( $names_extra ),* )
|
||||
( $( $names_skip_meta ),* )
|
||||
);
|
||||
};
|
||||
// add verify block to _() format
|
||||
@@ -385,6 +421,7 @@ macro_rules! benchmarks_iter {
|
||||
{ $( $where_clause:tt )* }
|
||||
( $( $names:tt )* )
|
||||
( $( $names_extra:tt )* )
|
||||
( $( $names_skip_meta:tt )* )
|
||||
$name:ident { $( $code:tt )* }: _ ( $origin:expr $( , $arg:expr )* )
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
@@ -393,6 +430,7 @@ macro_rules! benchmarks_iter {
|
||||
{ $( $where_clause )* }
|
||||
( $( $names )* )
|
||||
( $( $names_extra )* )
|
||||
( $( $names_skip_meta )* )
|
||||
$name { $( $code )* }: _ ( $origin $( , $arg )* )
|
||||
verify { }
|
||||
$( $rest )*
|
||||
@@ -404,6 +442,7 @@ macro_rules! benchmarks_iter {
|
||||
{ $( $where_clause:tt )* }
|
||||
( $( $names:tt )* )
|
||||
( $( $names_extra:tt )* )
|
||||
( $( $names_skip_meta:tt )* )
|
||||
$name:ident { $( $code:tt )* }: $dispatch:ident ( $origin:expr $( , $arg:expr )* )
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
@@ -412,6 +451,7 @@ macro_rules! benchmarks_iter {
|
||||
{ $( $where_clause )* }
|
||||
( $( $names )* )
|
||||
( $( $names_extra )* )
|
||||
( $( $names_skip_meta )* )
|
||||
$name { $( $code )* }: $dispatch ( $origin $( , $arg )* )
|
||||
verify { }
|
||||
$( $rest )*
|
||||
@@ -423,6 +463,7 @@ macro_rules! benchmarks_iter {
|
||||
{ $( $where_clause:tt )* }
|
||||
( $( $names:tt )* )
|
||||
( $( $names_extra:tt )* )
|
||||
( $( $names_skip_meta:tt )* )
|
||||
$name:ident { $( $code:tt )* }: $eval:block
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
@@ -431,6 +472,7 @@ macro_rules! benchmarks_iter {
|
||||
{ $( $where_clause )* }
|
||||
( $( $names )* )
|
||||
( $( $names_extra )* )
|
||||
( $( $names_skip_meta )* )
|
||||
$name { $( $code )* }: $eval
|
||||
verify { }
|
||||
$( $rest )*
|
||||
@@ -696,28 +738,40 @@ macro_rules! impl_benchmark {
|
||||
{ $( $instance:ident: $instance_bound:tt )? }
|
||||
( $( { $( $name_inst:ident )? } $name:ident )* )
|
||||
( $( $name_extra:ident ),* )
|
||||
( $( $name_skip_meta:ident ),* )
|
||||
) => {
|
||||
impl<T: Config $(<$instance>, $instance: $instance_bound )? >
|
||||
$crate::Benchmarking<$crate::BenchmarkResults> for Pallet<T $(, $instance)? >
|
||||
where T: frame_system::Config, $( $where_clause )*
|
||||
{
|
||||
fn benchmarks(extra: bool) -> $crate::Vec<&'static [u8]> {
|
||||
let mut all = $crate::vec![ $( stringify!($name).as_ref() ),* ];
|
||||
fn benchmarks(extra: bool) -> $crate::Vec<$crate::BenchmarkMetadata> {
|
||||
let mut all_names = $crate::vec![ $( stringify!($name).as_ref() ),* ];
|
||||
if !extra {
|
||||
let extra = [ $( stringify!($name_extra).as_ref() ),* ];
|
||||
all.retain(|x| !extra.contains(x));
|
||||
all_names.retain(|x| !extra.contains(x));
|
||||
}
|
||||
all
|
||||
all_names.into_iter().map(|benchmark| {
|
||||
let selected_benchmark = match benchmark {
|
||||
$( stringify!($name) => SelectedBenchmark::$name, )*
|
||||
_ => panic!("all benchmarks should be selectable"),
|
||||
};
|
||||
let components = <
|
||||
SelectedBenchmark as $crate::BenchmarkingSetup<T $(, $instance)?>
|
||||
>::components(&selected_benchmark);
|
||||
|
||||
$crate::BenchmarkMetadata {
|
||||
name: benchmark.as_bytes().to_vec(),
|
||||
components,
|
||||
}
|
||||
}).collect::<$crate::Vec<_>>()
|
||||
}
|
||||
|
||||
fn run_benchmark(
|
||||
extrinsic: &[u8],
|
||||
lowest_range_values: &[u32],
|
||||
highest_range_values: &[u32],
|
||||
steps: (u32, u32),
|
||||
_repeat: (u32, u32),
|
||||
c: &[($crate::BenchmarkParameter, u32)],
|
||||
whitelist: &[$crate::TrackedStorageKey],
|
||||
verify: bool,
|
||||
internal_repeats: u32,
|
||||
) -> Result<$crate::Vec<$crate::BenchmarkResults>, &'static str> {
|
||||
// Map the input to the selected benchmark.
|
||||
let extrinsic = $crate::sp_std::str::from_utf8(extrinsic)
|
||||
@@ -726,7 +780,6 @@ macro_rules! impl_benchmark {
|
||||
$( stringify!($name) => SelectedBenchmark::$name, )*
|
||||
_ => return Err("Could not find extrinsic."),
|
||||
};
|
||||
let mut results: $crate::Vec<$crate::BenchmarkResults> = $crate::Vec::new();
|
||||
|
||||
// Add whitelist to DB including whitelisted caller
|
||||
let mut whitelist = whitelist.to_vec();
|
||||
@@ -737,15 +790,10 @@ macro_rules! impl_benchmark {
|
||||
whitelist.push(whitelisted_caller_key.into());
|
||||
$crate::benchmarking::set_whitelist(whitelist);
|
||||
|
||||
let components = <
|
||||
SelectedBenchmark as $crate::BenchmarkingSetup<T $(, $instance)?>
|
||||
>::components(&selected_benchmark);
|
||||
let mut results: $crate::Vec<$crate::BenchmarkResults> = $crate::Vec::new();
|
||||
|
||||
let do_benchmark = |
|
||||
c: &[($crate::BenchmarkParameter, u32)],
|
||||
results: &mut $crate::Vec<$crate::BenchmarkResults>,
|
||||
verify: bool,
|
||||
| -> Result<(), &'static str> {
|
||||
// Always do at least one internal repeat...
|
||||
for _ in 0 .. internal_repeats.max(1) {
|
||||
// Set up the externalities environment for the setup we want to
|
||||
// benchmark.
|
||||
let closure_to_benchmark = <
|
||||
@@ -764,120 +812,68 @@ macro_rules! impl_benchmark {
|
||||
// Reset the read/write counter so we don't count operations in the setup process.
|
||||
$crate::benchmarking::reset_read_write_count();
|
||||
|
||||
if verify {
|
||||
closure_to_benchmark()?;
|
||||
// Time the extrinsic logic.
|
||||
$crate::log::trace!(
|
||||
target: "benchmark",
|
||||
"Start Benchmark: {:?}", c
|
||||
);
|
||||
|
||||
let start_pov = $crate::benchmarking::proof_size();
|
||||
let start_extrinsic = $crate::benchmarking::current_time();
|
||||
|
||||
closure_to_benchmark()?;
|
||||
|
||||
let finish_extrinsic = $crate::benchmarking::current_time();
|
||||
let end_pov = $crate::benchmarking::proof_size();
|
||||
|
||||
// Calculate the diff caused by the benchmark.
|
||||
let elapsed_extrinsic = finish_extrinsic.saturating_sub(start_extrinsic);
|
||||
let diff_pov = match (start_pov, end_pov) {
|
||||
(Some(start), Some(end)) => end.saturating_sub(start),
|
||||
_ => Default::default(),
|
||||
};
|
||||
|
||||
// Commit the changes to get proper write count
|
||||
$crate::benchmarking::commit_db();
|
||||
$crate::log::trace!(
|
||||
target: "benchmark",
|
||||
"End Benchmark: {} ns", elapsed_extrinsic
|
||||
);
|
||||
let read_write_count = $crate::benchmarking::read_write_count();
|
||||
$crate::log::trace!(
|
||||
target: "benchmark",
|
||||
"Read/Write Count {:?}", read_write_count
|
||||
);
|
||||
|
||||
// Time the storage root recalculation.
|
||||
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;
|
||||
|
||||
let skip_meta = [ $( stringify!($name_skip_meta).as_ref() ),* ];
|
||||
let read_and_written_keys = if (&skip_meta).contains(&extrinsic) {
|
||||
$crate::vec![(b"Skipped Metadata".to_vec(), 0, 0, false)]
|
||||
} else {
|
||||
// Time the extrinsic logic.
|
||||
$crate::log::trace!(
|
||||
target: "benchmark",
|
||||
"Start Benchmark: {:?}", c
|
||||
);
|
||||
$crate::benchmarking::get_read_and_written_keys()
|
||||
};
|
||||
|
||||
let start_pov = $crate::benchmarking::proof_size();
|
||||
let start_extrinsic = $crate::benchmarking::current_time();
|
||||
|
||||
closure_to_benchmark()?;
|
||||
|
||||
let finish_extrinsic = $crate::benchmarking::current_time();
|
||||
let end_pov = $crate::benchmarking::proof_size();
|
||||
|
||||
// Calculate the diff caused by the benchmark.
|
||||
let elapsed_extrinsic = finish_extrinsic.saturating_sub(start_extrinsic);
|
||||
let diff_pov = match (start_pov, end_pov) {
|
||||
(Some(start), Some(end)) => end.saturating_sub(start),
|
||||
_ => Default::default(),
|
||||
};
|
||||
|
||||
// Commit the changes to get proper write count
|
||||
$crate::benchmarking::commit_db();
|
||||
$crate::log::trace!(
|
||||
target: "benchmark",
|
||||
"End Benchmark: {} ns", elapsed_extrinsic
|
||||
);
|
||||
let read_write_count = $crate::benchmarking::read_write_count();
|
||||
$crate::log::trace!(
|
||||
target: "benchmark",
|
||||
"Read/Write Count {:?}", read_write_count
|
||||
);
|
||||
|
||||
// Time the storage root recalculation.
|
||||
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;
|
||||
|
||||
let read_and_written_keys = $crate::benchmarking::get_read_and_written_keys();
|
||||
|
||||
results.push($crate::BenchmarkResults {
|
||||
components: c.to_vec(),
|
||||
extrinsic_time: elapsed_extrinsic,
|
||||
storage_root_time: elapsed_storage_root,
|
||||
reads: read_write_count.0,
|
||||
repeat_reads: read_write_count.1,
|
||||
writes: read_write_count.2,
|
||||
repeat_writes: read_write_count.3,
|
||||
proof_size: diff_pov,
|
||||
keys: read_and_written_keys,
|
||||
});
|
||||
}
|
||||
results.push($crate::BenchmarkResults {
|
||||
components: c.to_vec(),
|
||||
extrinsic_time: elapsed_extrinsic,
|
||||
storage_root_time: elapsed_storage_root,
|
||||
reads: read_write_count.0,
|
||||
repeat_reads: read_write_count.1,
|
||||
writes: read_write_count.2,
|
||||
repeat_writes: read_write_count.3,
|
||||
proof_size: diff_pov,
|
||||
keys: read_and_written_keys,
|
||||
});
|
||||
|
||||
// Wipe the DB back to the genesis state.
|
||||
$crate::benchmarking::wipe_db();
|
||||
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let (current_step, total_steps) = steps;
|
||||
|
||||
if components.is_empty() {
|
||||
// The CLI could ask to do more steps than is sensible, so we skip those.
|
||||
if current_step == 0 {
|
||||
if verify {
|
||||
// If `--verify` is used, run the benchmark once to verify it would complete.
|
||||
do_benchmark(Default::default(), &mut $crate::Vec::new(), true)?;
|
||||
}
|
||||
do_benchmark(Default::default(), &mut results, false)?;
|
||||
}
|
||||
} else {
|
||||
// Select the component we will be benchmarking. Each component will be benchmarked.
|
||||
for (idx, (name, low, high)) in components.iter().enumerate() {
|
||||
|
||||
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 = (diff / total_steps).max(1);
|
||||
let num_of_steps = diff / step_size + 1;
|
||||
|
||||
// The CLI could ask to do more steps than is sensible, so we just skip those.
|
||||
if current_step >= num_of_steps {
|
||||
continue;
|
||||
}
|
||||
|
||||
// This is the value we will be testing for component `name`
|
||||
let component_value = lowest + step_size * current_step;
|
||||
|
||||
// Select the max value for all the other components.
|
||||
let c: $crate::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();
|
||||
|
||||
if verify {
|
||||
// If `--verify` is used, run the benchmark once to verify it would complete.
|
||||
do_benchmark(&c, &mut $crate::Vec::new(), true)?;
|
||||
}
|
||||
do_benchmark(&c, &mut results, false)?;
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(results);
|
||||
}
|
||||
}
|
||||
@@ -960,15 +956,14 @@ macro_rules! impl_benchmark_test {
|
||||
if components.is_empty() {
|
||||
execute_benchmark(Default::default())?;
|
||||
} else {
|
||||
for (_, (name, low, high)) in components.iter().enumerate() {
|
||||
for (name, low, high) in components.iter() {
|
||||
// Test only the low and high value, assuming values in the middle
|
||||
// won't break
|
||||
for component_value in $crate::vec![low, high] {
|
||||
// Select the max value for all the other components.
|
||||
let c: $crate::Vec<($crate::BenchmarkParameter, u32)> = components
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(_, (n, _, h))|
|
||||
.map(|(n, _, h)|
|
||||
if n == name {
|
||||
(*n, *component_value)
|
||||
} else {
|
||||
@@ -1206,7 +1201,8 @@ macro_rules! impl_benchmark_test_suite {
|
||||
|
||||
let mut anything_failed = false;
|
||||
println!("failing benchmark tests:");
|
||||
for benchmark_name in $bench_module::<$test>::benchmarks($extra) {
|
||||
for benchmark_metadata in $bench_module::<$test>::benchmarks($extra) {
|
||||
let benchmark_name = &benchmark_metadata.name;
|
||||
match std::panic::catch_unwind(|| {
|
||||
$bench_module::<$test>::test_bench_by_name(benchmark_name)
|
||||
}) {
|
||||
@@ -1233,30 +1229,21 @@ macro_rules! impl_benchmark_test_suite {
|
||||
pub fn show_benchmark_debug_info(
|
||||
instance_string: &[u8],
|
||||
benchmark: &[u8],
|
||||
lowest_range_values: &sp_std::prelude::Vec<u32>,
|
||||
highest_range_values: &sp_std::prelude::Vec<u32>,
|
||||
steps: &(u32, u32),
|
||||
repeat: &(u32, u32),
|
||||
components: &[(BenchmarkParameter, u32)],
|
||||
verify: &bool,
|
||||
error_message: &str,
|
||||
) -> sp_runtime::RuntimeString {
|
||||
sp_runtime::format_runtime_string!(
|
||||
"\n* Pallet: {}\n\
|
||||
* Benchmark: {}\n\
|
||||
* Lowest_range_values: {:?}\n\
|
||||
* Highest_range_values: {:?}\n\
|
||||
* Steps: {:?}\n\
|
||||
* Repeat: {:?}\n\
|
||||
* Components: {:?}\n\
|
||||
* Verify: {:?}\n\
|
||||
* Error message: {}",
|
||||
sp_std::str::from_utf8(instance_string)
|
||||
.expect("it's all just strings ran through the wasm interface. qed"),
|
||||
sp_std::str::from_utf8(benchmark)
|
||||
.expect("it's all just strings ran through the wasm interface. qed"),
|
||||
lowest_range_values,
|
||||
highest_range_values,
|
||||
steps.1,
|
||||
repeat.1,
|
||||
components,
|
||||
verify,
|
||||
error_message,
|
||||
)
|
||||
@@ -1334,12 +1321,9 @@ macro_rules! add_benchmark {
|
||||
let $crate::BenchmarkConfig {
|
||||
pallet,
|
||||
benchmark,
|
||||
lowest_range_values,
|
||||
highest_range_values,
|
||||
steps,
|
||||
repeat,
|
||||
selected_components,
|
||||
verify,
|
||||
extra,
|
||||
internal_repeats,
|
||||
} = config;
|
||||
if &pallet[..] == &name_string[..] {
|
||||
$batches.push($crate::BenchmarkBatch {
|
||||
@@ -1348,20 +1332,15 @@ macro_rules! add_benchmark {
|
||||
benchmark: benchmark.clone(),
|
||||
results: $( $location )*::run_benchmark(
|
||||
&benchmark[..],
|
||||
&lowest_range_values[..],
|
||||
&highest_range_values[..],
|
||||
*steps,
|
||||
*repeat,
|
||||
&selected_components[..],
|
||||
whitelist,
|
||||
*verify,
|
||||
*internal_repeats,
|
||||
).map_err(|e| {
|
||||
$crate::show_benchmark_debug_info(
|
||||
instance_string,
|
||||
benchmark,
|
||||
lowest_range_values,
|
||||
highest_range_values,
|
||||
steps,
|
||||
repeat,
|
||||
selected_components,
|
||||
verify,
|
||||
e,
|
||||
)
|
||||
@@ -1396,10 +1375,7 @@ macro_rules! list_benchmark {
|
||||
( $list:ident, $extra:ident, $name:path, $( $location:tt )* ) => (
|
||||
let pallet_string = stringify!($name).as_bytes();
|
||||
let instance_string = stringify!( $( $location )* ).as_bytes();
|
||||
let benchmarks = $( $location )*::benchmarks($extra)
|
||||
.iter()
|
||||
.map(|b| b.to_vec())
|
||||
.collect::<Vec<_>>();
|
||||
let benchmarks = $( $location )*::benchmarks($extra);
|
||||
let pallet_benchmarks = BenchmarkList {
|
||||
pallet: pallet_string.to_vec(),
|
||||
instance: instance_string.to_vec(),
|
||||
|
||||
@@ -199,6 +199,24 @@ mod benchmarks {
|
||||
variable_components {
|
||||
let b in ( T::LowerBound::get() ) .. T::UpperBound::get();
|
||||
}: dummy (RawOrigin::None, b.into())
|
||||
|
||||
#[extra]
|
||||
extra_benchmark {
|
||||
let b in 1 .. 1000;
|
||||
let caller = account::<T::AccountId>("caller", 0, 0);
|
||||
}: set_value(RawOrigin::Signed(caller), b.into())
|
||||
verify {
|
||||
assert_eq!(Value::get(), Some(b));
|
||||
}
|
||||
|
||||
#[skip_meta]
|
||||
skip_meta_benchmark {
|
||||
let b in 1 .. 1000;
|
||||
let caller = account::<T::AccountId>("caller", 0, 0);
|
||||
}: set_value(RawOrigin::Signed(caller), b.into())
|
||||
verify {
|
||||
assert_eq!(Value::get(), Some(b));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -76,6 +76,22 @@ pub struct BenchmarkBatch {
|
||||
pub results: Vec<BenchmarkResults>,
|
||||
}
|
||||
|
||||
// TODO: could probably make API cleaner here.
|
||||
/// The results of a single of benchmark, where time and db results are separated.
|
||||
#[derive(Encode, Decode, Clone, PartialEq, Debug)]
|
||||
pub struct BenchmarkBatchSplitResults {
|
||||
/// The pallet containing this benchmark.
|
||||
pub pallet: Vec<u8>,
|
||||
/// The instance of this pallet being benchmarked.
|
||||
pub instance: Vec<u8>,
|
||||
/// The extrinsic (or benchmark name) of this benchmark.
|
||||
pub benchmark: Vec<u8>,
|
||||
/// The extrinsic timing results from this benchmark.
|
||||
pub time_results: Vec<BenchmarkResults>,
|
||||
/// The db tracking results from this benchmark.
|
||||
pub db_results: Vec<BenchmarkResults>,
|
||||
}
|
||||
|
||||
/// Results from running benchmarks on a FRAME pallet.
|
||||
/// Contains duration of the function call in nanoseconds along with the benchmark parameters
|
||||
/// used for that benchmark result.
|
||||
@@ -99,21 +115,12 @@ pub struct BenchmarkConfig {
|
||||
pub pallet: Vec<u8>,
|
||||
/// The encoded name of the benchmark/extrinsic to run.
|
||||
pub benchmark: Vec<u8>,
|
||||
/// An optional manual override to the lowest values used in the `steps` range.
|
||||
pub lowest_range_values: Vec<u32>,
|
||||
/// An optional manual override to the highest values used in the `steps` range.
|
||||
pub highest_range_values: Vec<u32>,
|
||||
/// The number of samples to take across the range of values for components. (current_step,
|
||||
/// total_steps)
|
||||
pub steps: (u32, u32),
|
||||
/// The number times to repeat each benchmark to increase accuracy of results. (current_repeat,
|
||||
/// total_repeat)
|
||||
pub repeat: (u32, u32),
|
||||
/// The selected component values to use when running the benchmark.
|
||||
pub selected_components: Vec<(BenchmarkParameter, u32)>,
|
||||
/// Enable an extra benchmark iteration which runs the verification logic for a benchmark.
|
||||
pub verify: bool,
|
||||
/// Enable benchmarking of "extra" extrinsics, i.e. those that are not directly used in a
|
||||
/// pallet.
|
||||
pub extra: bool,
|
||||
/// Number of times to repeat benchmark within the Wasm environment. (versus in the client)
|
||||
pub internal_repeats: u32,
|
||||
}
|
||||
|
||||
/// A list of benchmarks available for a particular pallet and instance.
|
||||
@@ -123,7 +130,13 @@ pub struct BenchmarkConfig {
|
||||
pub struct BenchmarkList {
|
||||
pub pallet: Vec<u8>,
|
||||
pub instance: Vec<u8>,
|
||||
pub benchmarks: Vec<Vec<u8>>,
|
||||
pub benchmarks: Vec<BenchmarkMetadata>,
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode, Default, Clone, PartialEq, Debug)]
|
||||
pub struct BenchmarkMetadata {
|
||||
pub name: Vec<u8>,
|
||||
pub components: Vec<(BenchmarkParameter, u32, u32)>,
|
||||
}
|
||||
|
||||
sp_api::decl_runtime_apis! {
|
||||
@@ -228,27 +241,15 @@ pub trait Benchmarking<T> {
|
||||
/// Parameters
|
||||
/// - `extra`: Also return benchmarks marked "extra" which would otherwise not be
|
||||
/// needed for weight calculation.
|
||||
fn benchmarks(extra: bool) -> Vec<&'static [u8]>;
|
||||
fn benchmarks(extra: bool) -> Vec<BenchmarkMetadata>;
|
||||
|
||||
/// Run the benchmarks for this pallet.
|
||||
///
|
||||
/// Parameters
|
||||
/// - `name`: The name of extrinsic function or benchmark you want to benchmark encoded as
|
||||
/// bytes.
|
||||
/// - `lowest_range_values`: The lowest number for each range of parameters.
|
||||
/// - `highest_range_values`: The highest number for each range of parameters.
|
||||
/// - `steps`: The number of sample points you want to take across the range of parameters.
|
||||
/// (current_step, total_steps)
|
||||
/// - `repeat`: The total number times to repeat each benchmark to increase accuracy of results.
|
||||
/// (current_repeat, total_repeats)
|
||||
fn run_benchmark(
|
||||
name: &[u8],
|
||||
lowest_range_values: &[u32],
|
||||
highest_range_values: &[u32],
|
||||
steps: (u32, u32),
|
||||
repeat: (u32, u32),
|
||||
selected_components: &[(BenchmarkParameter, u32)],
|
||||
whitelist: &[TrackedStorageKey],
|
||||
verify: bool,
|
||||
internal_repeats: u32,
|
||||
) -> Result<Vec<T>, &'static str>;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user