From 255c201e735aaac55452559cbf38678871c2b149 Mon Sep 17 00:00:00 2001 From: Alexander Popiak Date: Mon, 11 May 2020 10:20:46 +0200 Subject: [PATCH] weight adjustments for identity and timestamp pallets (#5946) --- bin/node/executor/tests/basic.rs | 8 +- frame/identity/src/lib.rs | 280 ++++++++++++++++--------------- frame/timestamp/src/lib.rs | 8 +- 3 files changed, 152 insertions(+), 144 deletions(-) diff --git a/bin/node/executor/tests/basic.rs b/bin/node/executor/tests/basic.rs index caf3b7c0c7de5..47d5f3f3844e5 100644 --- a/bin/node/executor/tests/basic.rs +++ b/bin/node/executor/tests/basic.rs @@ -337,9 +337,9 @@ fn full_native_block_import_works() { let events = vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - // timestamp set call with weight 9_000_000 + 2 read + 1 write + // timestamp set call with weight 8_000_000 + 2 read + 1 write event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 9_000_000 + 2 * 25_000_000 + 1 * 100_000_000, class: DispatchClass::Mandatory, ..Default::default() } + DispatchInfo { weight: 8_000_000 + 2 * 25_000_000 + 1 * 100_000_000, class: DispatchClass::Mandatory, ..Default::default() } )), topics: vec![], }, @@ -392,9 +392,9 @@ fn full_native_block_import_works() { let events = vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - // timestamp set call with weight 9_000_000 + 2 read + 1 write + // timestamp set call with weight 8_000_000 + 2 read + 1 write event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 9_000_000 + 2 * 25_000_000 + 1 * 100_000_000, class: DispatchClass::Mandatory, ..Default::default() } + DispatchInfo { weight: 8_000_000 + 2 * 25_000_000 + 1 * 100_000_000, class: DispatchClass::Mandatory, ..Default::default() } )), topics: vec![], }, diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index 194a190ce62f0..c790203635ae6 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -463,97 +463,126 @@ decl_error! { /// Functions for calcuating the weight of dispatchables. mod weight_for { - use frame_support::weights::{RuntimeDbWeight, Weight}; + use frame_support::{traits::Get, weights::Weight}; + use super::Trait; + + /// Weight calculation for `add_registrar`. + /// + /// Based on benchmark: + /// 22.24 + R * 0.371 µs (min squares analysis) + pub(crate) fn add_registrar( + registrars: Weight + ) -> Weight { + T::DbWeight::get().reads_writes(1, 1) + + 23_000_000 // constant + + 380_000 * registrars // R + } /// Weight calculation for `set_identity`. - pub(crate) fn set_identity( - db: RuntimeDbWeight, - judgements: impl Into, - extra_fields: impl Into + /// + /// Based on benchmark: + /// 50.64 + R * 0.215 + X * 1.424 µs (min squares analysis) + pub(crate) fn set_identity( + judgements: Weight, + extra_fields: Weight ) -> Weight { - db.reads_writes(1, 1) - + 61_000_000 // constant - + 400_000 * judgements.into() // R - + 1_500_000 * extra_fields.into() // X + T::DbWeight::get().reads_writes(1, 1) + + 51_000_000 // constant + + 220_000 * judgements // R + + 1_500_000 * extra_fields // X } /// Weight calculation for `set_subs`. - pub(crate) fn set_subs( - db: RuntimeDbWeight, - old_subs: impl Into + Copy, - subs: impl Into + Copy + /// + /// Based on benchmark: + /// 36.21 + P * 2.481 + S * 3.633 µs (min squares analysis) + pub(crate) fn set_subs( + old_subs: Weight, + subs: Weight ) -> Weight { + let db = T::DbWeight::get(); db.reads(1) // storage-exists (`IdentityOf::contains_key`) - + db.reads_writes(1, old_subs.into()) // `SubsOf::get` read + P old DB deletions - + db.writes(subs.into() + 1) // S + 1 new DB writes - + 41_000_000 // constant - + 2_600_000 * old_subs.into() // P - + 3_700_000 * subs.into() // S + .saturating_add(db.reads_writes(1, old_subs)) // `SubsOf::get` read + P old DB deletions + .saturating_add(db.writes(subs + 1)) // S + 1 new DB writes + .saturating_add(37_000_000) // constant + .saturating_add(2_500_000 * old_subs) // P + .saturating_add(subs.saturating_mul(3_700_000)) // S } /// Weight calculation for `clear_identity`. - pub(crate) fn clear_identity( - db: RuntimeDbWeight, - judgements: impl Into, - subs: impl Into + Copy, - extra_fields: impl Into + /// + /// Based on benchmark: + /// 43.19 + R * 0.099 + S * 2.547 + X * 0.875 µs (min squares analysis) + pub(crate) fn clear_identity( + judgements: Weight, + subs: Weight, + extra_fields: Weight ) -> Weight { - db.reads_writes(2, subs.into() + 2) // S + 2 deletions - + 58_000_000 // constant - + 20_000 * judgements.into() // R - + 2_600_000 * subs.into() // S - + 900_000 * extra_fields.into() // X + T::DbWeight::get().reads_writes(2, subs + 2) // S + 2 deletions + + 44_000_000 // constant + + 100_000 * judgements // R + + 2_600_000 * subs // S + + 900_000 * extra_fields // X } /// Weight calculation for `request_judgement`. - pub(crate) fn request_judgement( - db: RuntimeDbWeight, - judgements: impl Into, - extra_fields: impl Into + /// + /// Based on benchmark: + /// 51.51 + R * 0.32 + X * 1.85 µs (min squares analysis) + pub(crate) fn request_judgement( + judgements: Weight, + extra_fields: Weight ) -> Weight { - db.reads_writes(2, 1) - + 60_000_000 // constant - + 510_000 * judgements.into() // R - + 1_700_000 * extra_fields.into() // X + T::DbWeight::get().reads_writes(2, 1) + + 52_000_000 // constant + + 400_000 * judgements // R + + 1_900_000 * extra_fields // X } /// Weight calculation for `cancel_request`. - pub(crate) fn cancel_request( - db: RuntimeDbWeight, - judgements: impl Into, - extra_fields: impl Into + /// + /// Based on benchmark: + /// 40.95 + R * 0.219 + X * 1.655 µs (min squares analysis) + pub(crate) fn cancel_request( + judgements: Weight, + extra_fields: Weight ) -> Weight { - db.reads_writes(1, 1) - + 52_000_000 // constant - + 400_000 * judgements.into() // R - + 1_700_000 * extra_fields.into() // X + T::DbWeight::get().reads_writes(1, 1) + + 41_000_000 // constant + + 300_000 * judgements // R + + 1_700_000 * extra_fields // X } /// Weight calculation for `provide_judgement`. - pub(crate) fn provide_judgement( - db: RuntimeDbWeight, - judgements: impl Into, - extra_fields: impl Into + /// + /// Based on benchmark: + /// 40.77 + R * 0.282 + X * 1.66 µs (min squares analysis) + pub(crate) fn provide_judgement( + judgements: Weight, + extra_fields: Weight ) -> Weight { - db.reads_writes(2, 1) - + 49_000_000 // constant - + 400_000 * judgements.into() // R - + 1_700_000 * extra_fields.into()// X + T::DbWeight::get().reads_writes(2, 1) + + 41_000_000 // constant + + 300_000 * judgements // R + + 1_700_000 * extra_fields// X } /// Weight calculation for `kill_identity`. - pub(crate) fn kill_identity( - db: RuntimeDbWeight, - judgements: impl Into, - subs: impl Into + Copy, - extra_fields: impl Into + /// + /// Based on benchmark: + /// 83.96 + R * 0.122 + S * 2.533 + X * 0.867 µs (min squares analysis) + pub(crate) fn kill_identity( + judgements: Weight, + subs: Weight, + extra_fields: Weight ) -> Weight { - db.reads_writes(2, subs.into() + 2) // 2 `take`s + S deletions + let db = T::DbWeight::get(); + db.reads_writes(2, subs + 2) // 2 `take`s + S deletions + db.reads_writes(1, 1) // balance ops - + 110_000_000 // constant - + 100_000 * judgements.into() // R - + 2_600_000 * subs.into() // S - + 900_000 * extra_fields.into() // X + + 84_000_000 // constant + + 130_000 * judgements // R + + 2_600_000 * subs // S + + 900_000 * extra_fields // X } } @@ -598,27 +627,26 @@ decl_module! { /// - `O(R)` where `R` registrar-count (governance-bounded and code-bounded). /// - One storage mutation (codec `O(R)`). /// - One event. - /// - Benchmark: 24.63 + R * 0.53 µs (min squares analysis) /// # - #[weight = T::DbWeight::get().reads_writes(1, 1) - + 25_000_000 // constant - + 550_000 * T::MaxRegistrars::get() as Weight // R - ] + #[weight = weight_for::add_registrar::(T::MaxRegistrars::get().into()) ] fn add_registrar(origin, account: T::AccountId) -> DispatchResultWithPostInfo { T::RegistrarOrigin::try_origin(origin) .map(|_| ()) .or_else(ensure_root)?; - let (i, registrar_count) = >::try_mutate(|registrars| -> Result<(RegistrarIndex, usize), DispatchError> { - ensure!((registrars.len() as u32) < T::MaxRegistrars::get(), Error::::TooManyRegistrars); - registrars.push(Some(RegistrarInfo { account, fee: Zero::zero(), fields: Default::default() })); - Ok(((registrars.len() - 1) as RegistrarIndex, registrars.len())) - })?; + let (i, registrar_count) = >::try_mutate( + |registrars| -> Result<(RegistrarIndex, usize), DispatchError> { + ensure!(registrars.len() < T::MaxRegistrars::get() as usize, Error::::TooManyRegistrars); + registrars.push(Some(RegistrarInfo { + account, fee: Zero::zero(), fields: Default::default() + })); + Ok(((registrars.len() - 1) as RegistrarIndex, registrars.len())) + } + )?; Self::deposit_event(RawEvent::RegistrarAdded(i)); - Ok(Some(T::DbWeight::get().reads_writes(1, 1) - + 25_000_000 + 550_000 * registrar_count as Weight).into()) + Ok(Some(weight_for::add_registrar::(registrar_count as Weight)).into()) } /// Set an account's identity information and reserve the appropriate deposit. @@ -639,12 +667,10 @@ decl_module! { /// - One balance reserve operation. /// - One storage mutation (codec-read `O(X' + R)`, codec-write `O(X + R)`). /// - One event. - /// - Benchmark: 59.44 + R * 0.389 + X * 1.434 µs (min squares analysis) /// # - #[weight = weight_for::set_identity( - T::DbWeight::get(), - T::MaxRegistrars::get(), // R - T::MaxAdditionalFields::get() // X + #[weight = weight_for::set_identity::( + T::MaxRegistrars::get().into(), // R + T::MaxAdditionalFields::get().into(), // X )] fn set_identity(origin, info: IdentityInfo) -> DispatchResultWithPostInfo { let sender = ensure_signed(origin)?; @@ -675,8 +701,7 @@ decl_module! { >::insert(&sender, id); Self::deposit_event(RawEvent::IdentitySet(sender)); - Ok(Some(weight_for::set_identity( - T::DbWeight::get(), + Ok(Some(weight_for::set_identity::( judgements, // R extra_fields as Weight // X )).into()) @@ -702,11 +727,9 @@ decl_module! { /// - One storage read (codec complexity `O(P)`). /// - One storage write (codec complexity `O(S)`). /// - One storage-exists (`IdentityOf::contains_key`). - /// - Benchmark: 39.43 + P * 2.522 + S * 3.698 µs (min squares analysis) /// # - #[weight = weight_for::set_subs( - T::DbWeight::get(), - T::MaxSubAccounts::get(), // P + #[weight = weight_for::set_subs::( + T::MaxSubAccounts::get().into(), // P subs.len() as Weight // S )] fn set_subs(origin, subs: Vec<(T::AccountId, Data)>) -> DispatchResultWithPostInfo { @@ -740,8 +763,7 @@ decl_module! { >::insert(&sender, (new_deposit, ids)); } - Ok(Some(weight_for::set_subs( - T::DbWeight::get(), + Ok(Some(weight_for::set_subs::( old_ids.len() as Weight, // P new_subs // S )).into()) @@ -764,15 +786,11 @@ decl_module! { /// - One balance-unreserve operation. /// - `2` storage reads and `S + 2` storage deletions. /// - One event. - /// - Benchmarks: - /// - 57.36 + R * 0.019 + S * 2.577 + X * 0.874 µs (median slopes analysis) - /// - 57.06 + R * 0.006 + S * 2.579 + X * 0.878 µs (min squares analysis) /// # - #[weight = weight_for::clear_identity( - T::DbWeight::get(), - T::MaxRegistrars::get(), // R - T::MaxSubAccounts::get(), // S - T::MaxAdditionalFields::get() // X + #[weight = weight_for::clear_identity::( + T::MaxRegistrars::get().into(), // R + T::MaxSubAccounts::get().into(), // S + T::MaxAdditionalFields::get().into(), // X )] fn clear_identity(origin) -> DispatchResultWithPostInfo { let sender = ensure_signed(origin)?; @@ -789,8 +807,7 @@ decl_module! { Self::deposit_event(RawEvent::IdentityCleared(sender, deposit)); - Ok(Some(weight_for::clear_identity( - T::DbWeight::get(), + Ok(Some(weight_for::clear_identity::( id.judgements.len() as Weight, // R sub_ids.len() as Weight, // S id.info.additional.len() as Weight // X @@ -819,12 +836,10 @@ decl_module! { /// - One balance-reserve operation. /// - Storage: 1 read `O(R)`, 1 mutate `O(X + R)`. /// - One event. - /// - Benchmark: 59.02 + R * 0.488 + X * 1.7 µs (min squares analysis) /// # - #[weight = weight_for::request_judgement( - T::DbWeight::get(), - T::MaxRegistrars::get(), // R - T::MaxAdditionalFields::get() // X + #[weight = weight_for::request_judgement::( + T::MaxRegistrars::get().into(), // R + T::MaxAdditionalFields::get().into(), // X )] fn request_judgement(origin, #[compact] reg_index: RegistrarIndex, @@ -855,7 +870,7 @@ decl_module! { Self::deposit_event(RawEvent::JudgementRequested(sender, reg_index)); - Ok(Some(weight_for::request_judgement(T::DbWeight::get(), judgements, extra_fields)).into()) + Ok(Some(weight_for::request_judgement::(judgements, extra_fields)).into()) } /// Cancel a previous request. @@ -873,13 +888,11 @@ decl_module! { /// - `O(R + X)`. /// - One balance-reserve operation. /// - One storage mutation `O(R + X)`. - /// - One event. - /// - Benchmark: 50.05 + R * 0.321 + X * 1.688 µs (min squares analysis) + /// - One event /// # - #[weight = weight_for::cancel_request( - T::DbWeight::get(), - T::MaxRegistrars::get(), // R - T::MaxAdditionalFields::get() // X + #[weight = weight_for::cancel_request::( + T::MaxRegistrars::get().into(), // R + T::MaxAdditionalFields::get().into(), // X )] fn cancel_request(origin, reg_index: RegistrarIndex) -> DispatchResultWithPostInfo { let sender = ensure_signed(origin)?; @@ -900,7 +913,7 @@ decl_module! { Self::deposit_event(RawEvent::JudgementUnrequested(sender, reg_index)); - Ok(Some(weight_for::request_judgement(T::DbWeight::get(), judgements, extra_fields)).into()) + Ok(Some(weight_for::request_judgement::(judgements, extra_fields)).into()) } /// Set the fee required for a judgement to be requested from a registrar. @@ -914,11 +927,11 @@ decl_module! { /// # /// - `O(R)`. /// - One storage mutation `O(R)`. - /// - Benchmark: 8.848 + R * 0.425 µs (min squares analysis) + /// - Benchmark: 7.315 + R * 0.329 µs (min squares analysis) /// # #[weight = T::DbWeight::get().reads_writes(1, 1) - + 9_000_000 // constant - + 430_000 * T::MaxRegistrars::get() as Weight // R + + 7_400_000 // constant + + 330_000 * T::MaxRegistrars::get() as Weight // R ] fn set_fee(origin, #[compact] index: RegistrarIndex, @@ -934,7 +947,7 @@ decl_module! { Ok(rs.len()) })?; Ok(Some(T::DbWeight::get().reads_writes(1, 1) - + 9_000_000 + 430_000 * registrars as Weight // R + + 7_400_000 + 330_000 * registrars as Weight // R ).into()) } @@ -949,11 +962,11 @@ decl_module! { /// # /// - `O(R)`. /// - One storage mutation `O(R)`. - /// - Benchmark: 10.05 + R * 0.438 µs (min squares analysis) + /// - Benchmark: 8.823 + R * 0.32 µs (min squares analysis) /// # #[weight = T::DbWeight::get().reads_writes(1, 1) - + 10_100_000 // constant - + 440_000 * T::MaxRegistrars::get() as Weight // R + + 8_900_000 // constant + + 320_000 * T::MaxRegistrars::get() as Weight // R ] fn set_account_id(origin, #[compact] index: RegistrarIndex, @@ -969,7 +982,7 @@ decl_module! { Ok(rs.len()) })?; Ok(Some(T::DbWeight::get().reads_writes(1, 1) - + 10_100_000 + 440_000 * registrars as Weight // R + + 8_900_000 + 320_000 * registrars as Weight // R ).into()) } @@ -984,11 +997,11 @@ decl_module! { /// # /// - `O(R)`. /// - One storage mutation `O(R)`. - /// - Benchmark: 8.985 + R * 0.413 µs (min squares analysis) + /// - Benchmark: 7.464 + R * 0.325 µs (min squares analysis) /// # #[weight = T::DbWeight::get().reads_writes(1, 1) - + 9_000_000 // constant - + 420_000 * T::MaxRegistrars::get() as Weight // R + + 7_500_000 // constant + + 330_000 * T::MaxRegistrars::get() as Weight // R ] fn set_fields(origin, #[compact] index: RegistrarIndex, @@ -1004,7 +1017,7 @@ decl_module! { Ok(rs.len()) })?; Ok(Some(T::DbWeight::get().reads_writes(1, 1) - + 9_000_000 + 420_000 * registrars as Weight // R + + 7_500_000 + 330_000 * registrars as Weight // R ).into()) } @@ -1026,12 +1039,10 @@ decl_module! { /// - Up to one account-lookup operation. /// - Storage: 1 read `O(R)`, 1 mutate `O(R + X)`. /// - One event. - /// - Benchmark: 47.77 + R * 0.336 + X * 1.664 µs (min squares analysis) /// # - #[weight = weight_for::provide_judgement( - T::DbWeight::get(), - T::MaxRegistrars::get(), // R - T::MaxAdditionalFields::get() // X + #[weight = weight_for::provide_judgement::( + T::MaxRegistrars::get().into(), // R + T::MaxAdditionalFields::get().into(), // X )] fn provide_judgement(origin, #[compact] reg_index: RegistrarIndex, @@ -1064,7 +1075,7 @@ decl_module! { >::insert(&target, id); Self::deposit_event(RawEvent::JudgementGiven(target, reg_index)); - Ok(Some(weight_for::provide_judgement(T::DbWeight::get(), judgements, extra_fields)).into()) + Ok(Some(weight_for::provide_judgement::(judgements, extra_fields)).into()) } /// Remove an account's identity and sub-account information and slash the deposits. @@ -1085,13 +1096,11 @@ decl_module! { /// - One balance-reserve operation. /// - `S + 2` storage mutations. /// - One event. - /// - Benchmark: 101.9 + R * 0.091 + S * 2.589 + X * 0.871 µs (min squares analysis) /// # - #[weight = weight_for::kill_identity( - T::DbWeight::get(), - T::MaxRegistrars::get(), // R - T::MaxSubAccounts::get(), // S - T::MaxAdditionalFields::get() // X + #[weight = weight_for::kill_identity::( + T::MaxRegistrars::get().into(), // R + T::MaxSubAccounts::get().into(), // S + T::MaxAdditionalFields::get().into(), // X )] fn kill_identity(origin, target: ::Source) -> DispatchResultWithPostInfo { T::ForceOrigin::try_origin(origin) @@ -1112,8 +1121,7 @@ decl_module! { Self::deposit_event(RawEvent::IdentityKilled(target, deposit)); - Ok(Some(weight_for::kill_identity( - T::DbWeight::get(), + Ok(Some(weight_for::kill_identity::( id.judgements.len() as Weight, // R sub_ids.len() as Weight, // S id.info.additional.len() as Weight // X diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index 31021e0887869..cb27fc711ff63 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -152,12 +152,12 @@ decl_module! { /// - `O(T)` where `T` complexity of `on_timestamp_set` /// - 1 storage read and 1 storage mutation (codec `O(1)`). (because of `DidUpdate::take` in `on_finalize`) /// - 1 event handler `on_timestamp_set` `O(T)`. - /// - Benchmark: 8.523 (min squares analysis) + /// - Benchmark: 7.678 (min squares analysis) /// - NOTE: This benchmark was done for a runtime with insignificant `on_timestamp_set` handlers. /// New benchmarking is needed when adding new handlers. /// # #[weight = ( - T::DbWeight::get().reads_writes(2, 1) + 9_000_000, + T::DbWeight::get().reads_writes(2, 1) + 8_000_000, DispatchClass::Mandatory )] fn set(origin, #[compact] now: T::Moment) { @@ -177,13 +177,13 @@ decl_module! { /// dummy `on_initialize` to return the weight used in `on_finalize`. fn on_initialize() -> Weight { // weight of `on_finalize` - 6_000_000 + 5_000_000 } /// # /// - `O(1)` /// - 1 storage deletion (codec `O(1)`). - /// - Benchmark: 5.105 µs (min squares analysis) + /// - Benchmark: 4.928 µs (min squares analysis) /// # fn on_finalize() { assert!(::DidUpdate::take(), "Timestamp must be updated once in the block");