benchmarking-cli: add --list-pallets and --all options (#3395)

closes #2844 

- adds `list-pallets` option which prints all unique available pallets
for benchmarking
```bash
./target/release/node benchmark pallet --list=pallets
```
- adds `all` option which runs benchmarks for all available pallets and
extrinsics (equivalent to `--pallet * --extrinsic *`)
```bash
./target/release/node benchmark pallet --all
```

- use the `list=pallets` syntax in `run_all_benchmarks.sh` script

cc ggwpez

---------

Co-authored-by: Bastian Köcher <git@kchr.de>
This commit is contained in:
Dastan
2024-02-21 15:56:09 +01:00
committed by GitHub
parent 5a06771ecc
commit 165d075a5f
4 changed files with 86 additions and 25 deletions
@@ -15,7 +15,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use super::{writer, PalletCmd};
use super::{writer, ListOutput, PalletCmd};
use codec::{Decode, Encode};
use frame_benchmarking::{
Analysis, BenchmarkBatch, BenchmarkBatchSplitResults, BenchmarkList, BenchmarkParameter,
@@ -39,7 +39,13 @@ use sp_externalities::Extensions;
use sp_keystore::{testing::MemoryKeystore, KeystoreExt};
use sp_runtime::traits::Hash;
use sp_state_machine::StateMachine;
use std::{collections::HashMap, fmt::Debug, fs, str::FromStr, time};
use std::{
collections::{BTreeMap, BTreeSet, HashMap},
fmt::Debug,
fs,
str::FromStr,
time,
};
/// Logging target
const LOG_TARGET: &'static str = "frame::benchmark::pallet";
@@ -191,6 +197,7 @@ impl PalletCmd {
let spec = config.chain_spec;
let pallet = self.pallet.clone().unwrap_or_default();
let pallet = pallet.as_bytes();
let extrinsic = self.extrinsic.clone().unwrap_or_default();
let extrinsic_split: Vec<&str> = extrinsic.split(',').collect();
let extrinsics: Vec<_> = extrinsic_split.iter().map(|x| x.trim().as_bytes()).collect();
@@ -309,9 +316,8 @@ impl PalletCmd {
return Err("No benchmarks found which match your input.".into())
}
if self.list {
// List benchmarks instead of running them
list_benchmark(benchmarks_to_run);
if let Some(list_output) = self.list {
list_benchmark(benchmarks_to_run, list_output, self.no_csv_header);
return Ok(())
}
@@ -755,19 +761,43 @@ impl CliConfiguration for PalletCmd {
/// List the benchmarks available in the runtime, in a CSV friendly format.
fn list_benchmark(
mut benchmarks_to_run: Vec<(
benchmarks_to_run: Vec<(
Vec<u8>,
Vec<u8>,
Vec<(BenchmarkParameter, u32, u32)>,
Vec<(String, String)>,
)>,
list_output: ListOutput,
no_csv_header: bool,
) {
// Sort and de-dub by pallet and function name.
benchmarks_to_run.sort_by(|(pa, sa, _, _), (pb, sb, _, _)| (pa, sa).cmp(&(pb, sb)));
benchmarks_to_run.dedup_by(|(pa, sa, _, _), (pb, sb, _, _)| (pa, sa) == (pb, sb));
let mut benchmarks = BTreeMap::new();
println!("pallet, benchmark");
for (pallet, extrinsic, _, _) in benchmarks_to_run {
println!("{}, {}", String::from_utf8_lossy(&pallet), String::from_utf8_lossy(&extrinsic));
// Sort and de-dub by pallet and function name.
benchmarks_to_run.iter().for_each(|(pallet, extrinsic, _, _)| {
benchmarks
.entry(String::from_utf8_lossy(pallet).to_string())
.or_insert_with(BTreeSet::new)
.insert(String::from_utf8_lossy(extrinsic).to_string());
});
match list_output {
ListOutput::All => {
if !no_csv_header {
println!("pallet,extrinsic");
}
for (pallet, extrinsics) in benchmarks {
for extrinsic in extrinsics {
println!("{pallet},{extrinsic}");
}
}
},
ListOutput::Pallets => {
if !no_csv_header {
println!("pallet");
};
for pallet in benchmarks.keys() {
println!("{pallet}");
}
},
}
}