From f1dd9086e08e01d00848892172a30eac56be0b6d Mon Sep 17 00:00:00 2001 From: ljedrz Date: Fri, 5 Apr 2024 10:41:29 +0200 Subject: [PATCH 1/2] perf: use a parallel sort to order txs while speculating Signed-off-by: ljedrz --- synthesizer/src/vm/finalize.rs | 11 ++++++++--- utilities/src/parallel.rs | 12 ++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/synthesizer/src/vm/finalize.rs b/synthesizer/src/vm/finalize.rs index 7b59956b28..3a538c5546 100644 --- a/synthesizer/src/vm/finalize.rs +++ b/synthesizer/src/vm/finalize.rs @@ -15,6 +15,7 @@ use super::*; use ledger_committee::{MAX_DELEGATORS, MIN_DELEGATOR_STAKE, MIN_VALIDATOR_STAKE}; +use utilities::cfg_sort_unstable_by; impl> VM { /// Speculates on the given list of transactions in the VM. @@ -835,9 +836,13 @@ impl> VM { } // Sort the valid and aborted transactions based on their position in the original list. - let position: IndexMap<_, _> = cfg_iter!(transactions).enumerate().map(|(i, &tx)| (tx.id(), i)).collect(); - valid_transactions.sort_by(|a, b| position.get(&a.id()).cmp(&position.get(&b.id()))); - aborted_transactions.sort_by(|a, b| position.get(&a.0.id()).cmp(&position.get(&b.0.id()))); + let position: IndexSet<_> = transactions.iter().map(|tx| tx.id()).collect(); + cfg_sort_unstable_by!(valid_transactions, |a, b| position + .get_index_of(&a.id()) + .cmp(&position.get_index_of(&b.id()))); + cfg_sort_unstable_by!(aborted_transactions, |a, b| position + .get_index_of(&a.0.id()) + .cmp(&position.get_index_of(&b.0.id()))); // Return the valid and invalid transactions. Ok((valid_transactions, aborted_transactions)) diff --git a/utilities/src/parallel.rs b/utilities/src/parallel.rs index 05d95978af..8d74eb89bb 100644 --- a/utilities/src/parallel.rs +++ b/utilities/src/parallel.rs @@ -268,3 +268,15 @@ macro_rules! cfg_zip_fold { result }}; } + +/// Performs an unstable sort +#[macro_export] +macro_rules! cfg_sort_unstable_by { + ($self: expr, $closure: expr) => {{ + #[cfg(feature = "serial")] + $self.sort_unstable_by($closure); + + #[cfg(not(feature = "serial"))] + $self.par_sort_unstable_by($closure); + }}; +} From 38fe8ff8d5cc8a9960911f037874b903ed0f69f3 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Sun, 7 Apr 2024 13:33:02 +0200 Subject: [PATCH 2/2] perf: chache the key when sorting txs while speculating Signed-off-by: ljedrz --- synthesizer/src/vm/finalize.rs | 10 +++------- utilities/src/parallel.rs | 12 ++++++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/synthesizer/src/vm/finalize.rs b/synthesizer/src/vm/finalize.rs index 3a538c5546..46d1598166 100644 --- a/synthesizer/src/vm/finalize.rs +++ b/synthesizer/src/vm/finalize.rs @@ -15,7 +15,7 @@ use super::*; use ledger_committee::{MAX_DELEGATORS, MIN_DELEGATOR_STAKE, MIN_VALIDATOR_STAKE}; -use utilities::cfg_sort_unstable_by; +use utilities::cfg_sort_by_cached_key; impl> VM { /// Speculates on the given list of transactions in the VM. @@ -837,12 +837,8 @@ impl> VM { // Sort the valid and aborted transactions based on their position in the original list. let position: IndexSet<_> = transactions.iter().map(|tx| tx.id()).collect(); - cfg_sort_unstable_by!(valid_transactions, |a, b| position - .get_index_of(&a.id()) - .cmp(&position.get_index_of(&b.id()))); - cfg_sort_unstable_by!(aborted_transactions, |a, b| position - .get_index_of(&a.0.id()) - .cmp(&position.get_index_of(&b.0.id()))); + cfg_sort_by_cached_key!(valid_transactions, |tx| position.get_index_of(&tx.id())); + cfg_sort_by_cached_key!(aborted_transactions, |tx| position.get_index_of(&tx.0.id())); // Return the valid and invalid transactions. Ok((valid_transactions, aborted_transactions)) diff --git a/utilities/src/parallel.rs b/utilities/src/parallel.rs index 8d74eb89bb..be2520f7ef 100644 --- a/utilities/src/parallel.rs +++ b/utilities/src/parallel.rs @@ -280,3 +280,15 @@ macro_rules! cfg_sort_unstable_by { $self.par_sort_unstable_by($closure); }}; } + +/// Performs a sort that caches the extracted keys +#[macro_export] +macro_rules! cfg_sort_by_cached_key { + ($self: expr, $closure: expr) => {{ + #[cfg(feature = "serial")] + $self.sort_by_cached_key($closure); + + #[cfg(not(feature = "serial"))] + $self.par_sort_by_cached_key($closure); + }}; +}