diff --git a/substrate/bin/node/bench/src/import.rs b/substrate/bin/node/bench/src/import.rs index 1fd2bbdecc..10f5ee8dca 100644 --- a/substrate/bin/node/bench/src/import.rs +++ b/substrate/bin/node/bench/src/import.rs @@ -30,7 +30,7 @@ use std::borrow::Cow; -use node_testing::bench::{BenchDb, Profile, BlockType, KeyTypes}; +use node_testing::bench::{BenchDb, Profile, BlockType, KeyTypes, DatabaseType}; use node_primitives::Block; use sc_client_api::backend::Backend; use sp_runtime::generic::BlockId; @@ -72,6 +72,7 @@ pub struct ImportBenchmarkDescription { pub key_types: KeyTypes, pub block_type: BlockType, pub size: SizeType, + pub database_type: DatabaseType, } pub struct ImportBenchmark { @@ -101,6 +102,11 @@ impl core::BenchmarkDescription for ImportBenchmarkDescription { BlockType::Noop(_) => path.push("noop"), } + match self.database_type { + DatabaseType::RocksDb => path.push("rocksdb"), + DatabaseType::ParityDb => path.push("paritydb"), + } + path.push(&format!("{}", self.size)); path @@ -109,6 +115,7 @@ impl core::BenchmarkDescription for ImportBenchmarkDescription { fn setup(self: Box) -> Box { let profile = self.profile; let mut bench_db = BenchDb::with_key_types( + self.database_type, 50_000, self.key_types ); @@ -122,9 +129,10 @@ impl core::BenchmarkDescription for ImportBenchmarkDescription { fn name(&self) -> Cow<'static, str> { format!( - "Import benchmark ({:?}, {:?})", + "Import benchmark ({:?}, {:?}, {:?} backend)", self.block_type, self.profile, + self.database_type, ).into() } } diff --git a/substrate/bin/node/bench/src/main.rs b/substrate/bin/node/bench/src/main.rs index e627f07c3d..df7e4c2da2 100644 --- a/substrate/bin/node/bench/src/main.rs +++ b/substrate/bin/node/bench/src/main.rs @@ -26,7 +26,7 @@ use crate::core::{run_benchmark, Mode as BenchmarkMode}; use crate::tempdb::DatabaseType; use import::{ImportBenchmarkDescription, SizeType}; use trie::{TrieReadBenchmarkDescription, TrieWriteBenchmarkDescription, DatabaseSize}; -use node_testing::bench::{Profile, KeyTypes, BlockType}; +use node_testing::bench::{Profile, KeyTypes, BlockType, DatabaseType as BenchDataBaseType}; use structopt::StructOpt; #[derive(Debug, StructOpt)] @@ -90,18 +90,21 @@ fn main() { BlockType::RandomTransfersReaping(txs), BlockType::Noop(txs), ].iter() { - import_benchmarks.push((profile.clone(), size.clone(), block_type.clone())); + for database_type in [BenchDataBaseType::RocksDb, BenchDataBaseType::ParityDb].iter() { + import_benchmarks.push((profile, size, block_type.clone(), database_type)); + } } } } let benchmarks = matrix!( - (profile, size, block_type) in import_benchmarks.iter() => + (profile, size, block_type, database_type) in import_benchmarks.into_iter() => ImportBenchmarkDescription { profile: *profile, key_types: KeyTypes::Sr25519, size: *size, - block_type: *block_type, + block_type: block_type, + database_type: *database_type, }, (size, db_type) in [ @@ -128,8 +131,14 @@ fn main() { ); if opt.list { + println!("Available benchmarks:"); + if let Some(filter) = opt.filter.as_ref() { + println!("\t(filtered by \"{}\")", filter); + } for benchmark in benchmarks.iter() { - log::info!("{}: {}", benchmark.name(), benchmark.path().full()) + if opt.filter.as_ref().map(|f| benchmark.path().has(f)).unwrap_or(true) { + println!("{}: {}", benchmark.name(), benchmark.path().full()) + } } return; } diff --git a/substrate/bin/node/testing/src/bench.rs b/substrate/bin/node/testing/src/bench.rs index cdc9cc86e5..b784d9f42b 100644 --- a/substrate/bin/node/testing/src/bench.rs +++ b/substrate/bin/node/testing/src/bench.rs @@ -20,7 +20,7 @@ //! can pregenerate seed database and `clone` it for every iteration of your benchmarks //! or tests to get consistent, smooth benchmark experience! -use std::{sync::Arc, path::Path, collections::BTreeMap}; +use std::{sync::Arc, path::{Path, PathBuf}, collections::BTreeMap}; use node_primitives::Block; use crate::client::{Client, Backend}; @@ -94,11 +94,13 @@ impl BenchPair { pub struct BenchDb { keyring: BenchKeyring, directory_guard: Guard, + database_type: DatabaseType, } impl Clone for BenchDb { fn clone(&self) -> Self { let keyring = self.keyring.clone(); + let database_type = self.database_type; let dir = tempfile::tempdir().expect("temp dir creation failed"); let seed_dir = self.directory_guard.0.path(); @@ -122,7 +124,7 @@ impl Clone for BenchDb { &fs_extra::dir::CopyOptions::new(), ).expect("Copy of seed database is ok"); - BenchDb { keyring, directory_guard: Guard(dir) } + BenchDb { keyring, directory_guard: Guard(dir), database_type } } } @@ -137,6 +139,29 @@ pub enum BlockType { Noop(usize), } +/// Type of backend database. +#[derive(Debug, PartialEq, Clone, Copy)] +pub enum DatabaseType { + /// RocksDb backend. + RocksDb, + /// Parity DB backend. + ParityDb, +} + +impl DatabaseType { + fn into_settings(self, path: PathBuf) -> sc_client_db::DatabaseSettingsSrc { + match self { + Self::RocksDb => sc_client_db::DatabaseSettingsSrc::RocksDb { + path, + cache_size: 512, + }, + Self::ParityDb => sc_client_db::DatabaseSettingsSrc::ParityDb { + path, + } + } + } +} + impl BlockType { /// Number of transactions for this block type. pub fn transactions(&self) -> usize { @@ -181,7 +206,11 @@ impl BenchDb { /// /// See [`new`] method documentation for more information about the purpose /// of this structure. - pub fn with_key_types(keyring_length: usize, key_types: KeyTypes) -> Self { + pub fn with_key_types( + database_type: DatabaseType, + keyring_length: usize, + key_types: KeyTypes, + ) -> Self { let keyring = BenchKeyring::new(keyring_length, key_types); let dir = tempfile::tempdir().expect("temp dir creation failed"); @@ -190,10 +219,10 @@ impl BenchDb { "Created seed db at {}", dir.path().to_string_lossy(), ); - let (_client, _backend) = Self::bench_client(dir.path(), Profile::Native, &keyring); + let (_client, _backend) = Self::bench_client(database_type, dir.path(), Profile::Native, &keyring); let directory_guard = Guard(dir); - BenchDb { keyring, directory_guard } + BenchDb { keyring, directory_guard, database_type } } /// New immutable benchmarking database. @@ -204,8 +233,8 @@ impl BenchDb { /// You can `clone` this database or you can `create_context` from it /// (which also does `clone`) to run actual operation against new database /// which will be identical to the original. - pub fn new(keyring_length: usize) -> Self { - Self::with_key_types(keyring_length, KeyTypes::Sr25519) + pub fn new(database_type: DatabaseType, keyring_length: usize) -> Self { + Self::with_key_types(database_type, keyring_length, KeyTypes::Sr25519) } // This should return client that is doing everything that full node @@ -213,15 +242,17 @@ impl BenchDb { // // - This client should use best wasm execution method. // - This client should work with real database only. - fn bench_client(dir: &std::path::Path, profile: Profile, keyring: &BenchKeyring) -> (Client, std::sync::Arc) { + fn bench_client( + database_type: DatabaseType, + dir: &std::path::Path, + profile: Profile, + keyring: &BenchKeyring, + ) -> (Client, std::sync::Arc) { let db_config = sc_client_db::DatabaseSettings { state_cache_size: 16*1024*1024, state_cache_child_ratio: Some((0, 100)), pruning: PruningMode::ArchiveAll, - source: sc_client_db::DatabaseSettingsSrc::RocksDb { - path: dir.into(), - cache_size: 512, - }, + source: database_type.into_settings(dir.into()), }; let (client, backend) = sc_service::new_client( @@ -242,6 +273,7 @@ impl BenchDb { /// Generate new block using this database. pub fn generate_block(&mut self, block_type: BlockType) -> Block { let (client, _backend) = Self::bench_client( + self.database_type, self.directory_guard.path(), Profile::Wasm, &self.keyring, @@ -354,8 +386,13 @@ impl BenchDb { /// Clone this database and create context for testing/benchmarking. pub fn create_context(&self, profile: Profile) -> BenchContext { - let BenchDb { directory_guard, keyring } = self.clone(); - let (client, backend) = Self::bench_client(directory_guard.path(), profile, &keyring); + let BenchDb { directory_guard, keyring, database_type } = self.clone(); + let (client, backend) = Self::bench_client( + database_type, + directory_guard.path(), + profile, + &keyring + ); BenchContext { client, backend, db_guard: directory_guard,