perf: use Vec::with_capacity and reserve_exact (#11904)

This commit is contained in:
nk_ysg
2024-10-21 19:59:09 +08:00
committed by GitHub
parent aba4991d0a
commit f25cceb9f9
13 changed files with 22 additions and 17 deletions

View File

@ -228,11 +228,11 @@ impl Chain {
/// ///
/// Attachment includes block number, block hash, transaction hash and transaction index. /// Attachment includes block number, block hash, transaction hash and transaction index.
pub fn receipts_with_attachment(&self) -> Vec<BlockReceipts> { pub fn receipts_with_attachment(&self) -> Vec<BlockReceipts> {
let mut receipt_attach = Vec::new(); let mut receipt_attach = Vec::with_capacity(self.blocks().len());
for ((block_num, block), receipts) in for ((block_num, block), receipts) in
self.blocks().iter().zip(self.execution_outcome.receipts().iter()) self.blocks().iter().zip(self.execution_outcome.receipts().iter())
{ {
let mut tx_receipts = Vec::new(); let mut tx_receipts = Vec::with_capacity(receipts.len());
for (tx, receipt) in block.body.transactions().zip(receipts.iter()) { for (tx, receipt) in block.body.transactions().zip(receipts.iter()) {
tx_receipts.push(( tx_receipts.push((
tx.hash(), tx.hash(),

View File

@ -2324,9 +2324,9 @@ mod tests {
let original = EnrForkIdEntry { let original = EnrForkIdEntry {
fork_id: ForkId { hash: ForkHash([0xdc, 0xe9, 0x6c, 0x2d]), next: 0 }, fork_id: ForkId { hash: ForkHash([0xdc, 0xe9, 0x6c, 0x2d]), next: 0 },
}; };
let mut encoded = Vec::new();
original.encode(&mut encoded);
let expected: [u8; 8] = [0xc7, 0xc6, 0x84, 0xdc, 0xe9, 0x6c, 0x2d, 0x80]; let expected: [u8; 8] = [0xc7, 0xc6, 0x84, 0xdc, 0xe9, 0x6c, 0x2d, 0x80];
let mut encoded = Vec::with_capacity(expected.len());
original.encode(&mut encoded);
assert_eq!(&expected[..], encoded.as_slice()); assert_eq!(&expected[..], encoded.as_slice());
} }

View File

@ -305,7 +305,7 @@ pub fn calculate_reward_percentiles_for_block(
// the percentiles are monotonically increasing. // the percentiles are monotonically increasing.
let mut tx_index = 0; let mut tx_index = 0;
let mut cumulative_gas_used = transactions.first().map(|tx| tx.gas_used).unwrap_or_default(); let mut cumulative_gas_used = transactions.first().map(|tx| tx.gas_used).unwrap_or_default();
let mut rewards_in_block = Vec::new(); let mut rewards_in_block = Vec::with_capacity(percentiles.len());
for percentile in percentiles { for percentile in percentiles {
// Empty blocks should return in a zero row // Empty blocks should return in a zero row
if transactions.is_empty() { if transactions.is_empty() {

View File

@ -183,7 +183,7 @@ pub fn build_block<T: TransactionCompat>(
) -> Result<SimulatedBlock<Block<T::Transaction>>, EthApiError> { ) -> Result<SimulatedBlock<Block<T::Transaction>>, EthApiError> {
let mut calls: Vec<SimCallResult> = Vec::with_capacity(results.len()); let mut calls: Vec<SimCallResult> = Vec::with_capacity(results.len());
let mut senders = Vec::with_capacity(results.len()); let mut senders = Vec::with_capacity(results.len());
let mut receipts = Vec::new(); let mut receipts = Vec::with_capacity(results.len());
let mut log_index = 0; let mut log_index = 0;
for (transaction_index, ((sender, result), tx)) in for (transaction_index, ((sender, result), tx)) in

View File

@ -421,8 +421,8 @@ mod tests {
let mut rng = generators::rng(); let mut rng = generators::rng();
// Build mock data // Build mock data
let mut gas_used_ratios = Vec::new(); let mut gas_used_ratios = Vec::with_capacity(block_count as usize);
let mut base_fees_per_gas = Vec::new(); let mut base_fees_per_gas = Vec::with_capacity(block_count as usize);
let mut last_header = None; let mut last_header = None;
let mut parent_hash = B256::default(); let mut parent_hash = B256::default();
@ -444,8 +444,9 @@ mod tests {
last_header = Some(header.clone()); last_header = Some(header.clone());
parent_hash = hash; parent_hash = hash;
let mut transactions = vec![]; const TOTAL_TRANSACTIONS: usize = 100;
for _ in 0..100 { let mut transactions = Vec::with_capacity(TOTAL_TRANSACTIONS);
for _ in 0..TOTAL_TRANSACTIONS {
let random_fee: u128 = rng.gen(); let random_fee: u128 = rng.gen();
if let Some(base_fee_per_gas) = header.base_fee_per_gas { if let Some(base_fee_per_gas) = header.base_fee_per_gas {

View File

@ -40,7 +40,7 @@ impl DevSigner {
/// Generates provided number of random dev signers /// Generates provided number of random dev signers
/// which satisfy [`EthSigner`] trait /// which satisfy [`EthSigner`] trait
pub fn random_signers(num: u32) -> Vec<Box<dyn EthSigner + 'static>> { pub fn random_signers(num: u32) -> Vec<Box<dyn EthSigner + 'static>> {
let mut signers = Vec::new(); let mut signers = Vec::with_capacity(num as usize);
for _ in 0..num { for _ in 0..num {
let sk = PrivateKeySigner::random_with(&mut rand::thread_rng()); let sk = PrivateKeySigner::random_with(&mut rand::thread_rng());

View File

@ -34,7 +34,9 @@ impl<Provider> PipelineBuilder<Provider> {
/// [`builder`][StageSet::builder] on the set which will convert it to a /// [`builder`][StageSet::builder] on the set which will convert it to a
/// [`StageSetBuilder`][crate::StageSetBuilder]. /// [`StageSetBuilder`][crate::StageSetBuilder].
pub fn add_stages<Set: StageSet<Provider>>(mut self, set: Set) -> Self { pub fn add_stages<Set: StageSet<Provider>>(mut self, set: Set) -> Self {
for stage in set.builder().build() { let states = set.builder().build();
self.stages.reserve_exact(states.len());
for stage in states {
self.stages.push(stage); self.stages.push(stage);
} }
self self

View File

@ -917,7 +917,8 @@ mod tests {
return Poll::Ready(None) return Poll::Ready(None)
} }
let mut response = Vec::default(); let mut response =
Vec::with_capacity(std::cmp::min(this.headers.len(), this.batch_size as usize));
while let Some(header) = this.headers.pop_front() { while let Some(header) = this.headers.pop_front() {
if header.is_empty() { if header.is_empty() {
response.push(BlockResponse::Empty(header)) response.push(BlockResponse::Empty(header))

View File

@ -505,7 +505,7 @@ mod tests {
#[test] #[test]
fn compact_address() { fn compact_address() {
let mut buf = vec![]; let mut buf = Vec::with_capacity(21);
assert_eq!(Address::ZERO.to_compact(&mut buf), 20); assert_eq!(Address::ZERO.to_compact(&mut buf), 20);
assert_eq!(buf, vec![0; 20]); assert_eq!(buf, vec![0; 20]);

View File

@ -213,7 +213,7 @@ impl Compression for Zstd {
return Err(NippyJarError::ColumnLenMismatch(self.columns, columns.len())) return Err(NippyJarError::ColumnLenMismatch(self.columns, columns.len()))
} }
let mut dictionaries = vec![]; let mut dictionaries = Vec::with_capacity(columns.len());
for column in columns { for column in columns {
// ZSTD requires all training data to be continuous in memory, alongside the size of // ZSTD requires all training data to be continuous in memory, alongside the size of
// each entry // each entry

View File

@ -1364,13 +1364,13 @@ impl TransactionsProviderExt for StaticFileProvider {
// chunks are too big, there will be idle threads waiting for work. Choosing an // chunks are too big, there will be idle threads waiting for work. Choosing an
// arbitrary smaller value to make sure it doesn't happen. // arbitrary smaller value to make sure it doesn't happen.
let chunk_size = 100; let chunk_size = 100;
let mut channels = Vec::new();
// iterator over the chunks // iterator over the chunks
let chunks = tx_range let chunks = tx_range
.clone() .clone()
.step_by(chunk_size) .step_by(chunk_size)
.map(|start| start..std::cmp::min(start + chunk_size as u64, tx_range.end)); .map(|start| start..std::cmp::min(start + chunk_size as u64, tx_range.end));
let mut channels = Vec::with_capacity(tx_range_size.div_ceil(chunk_size));
for chunk_range in chunks { for chunk_range in chunks {
let (channel_tx, channel_rx) = mpsc::channel(); let (channel_tx, channel_rx) = mpsc::channel();

View File

@ -66,7 +66,7 @@ fn generate_many_transactions(senders: usize, max_depth: usize) -> Vec<MockTrans
let rng = TestRng::from_seed(RngAlgorithm::ChaCha, &SEED); let rng = TestRng::from_seed(RngAlgorithm::ChaCha, &SEED);
let mut runner = TestRunner::new_with_rng(config, rng); let mut runner = TestRunner::new_with_rng(config, rng);
let mut txs = Vec::new(); let mut txs = Vec::with_capacity(senders);
for idx in 0..senders { for idx in 0..senders {
// modulo max_depth so we know it is bounded, plus one so the minimum is always 1 // modulo max_depth so we know it is bounded, plus one so the minimum is always 1
let depth = any::<usize>().new_tree(&mut runner).unwrap().current() % max_depth + 1; let depth = any::<usize>().new_tree(&mut runner).unwrap().current() % max_depth + 1;

View File

@ -109,6 +109,7 @@ where
match self.pool.get_all_blobs_exact(txs.iter().map(|(tx, _)| tx.hash()).collect()) { match self.pool.get_all_blobs_exact(txs.iter().map(|(tx, _)| tx.hash()).collect()) {
Ok(blobs) => { Ok(blobs) => {
actions_to_queue.reserve_exact(txs.len());
for ((tx, _), sidecar) in txs.iter().zip(blobs.iter()) { for ((tx, _), sidecar) in txs.iter().zip(blobs.iter()) {
let transaction = BlobTransaction::try_from_signed(tx.clone(), sidecar.clone()) let transaction = BlobTransaction::try_from_signed(tx.clone(), sidecar.clone())
.expect("should not fail to convert blob tx if it is already eip4844"); .expect("should not fail to convert blob tx if it is already eip4844");