From 2e4ff91283deda6fc7e6a4d81e5c0967a21bf2db Mon Sep 17 00:00:00 2001 From: Dunqing <29533304+Dunqing@users.noreply.github.com> Date: Mon, 27 Jan 2025 03:44:34 +0000 Subject: [PATCH] perf(manger): Revert "perf(manger): remove useless tmp_bindings (#8735)" (#8741) #8735 removes `tmp_bindings` and then calls `Iterator::sorted_unstabled` instead, I thought it ideal but after I saw performance regression, I looked at `sorted_unstabled`'s implementation, and it will cause an allocation every run, but `tmp_bindings` only allocate once, then clear and reuse it in that loop. --- crates/oxc_mangler/src/lib.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/crates/oxc_mangler/src/lib.rs b/crates/oxc_mangler/src/lib.rs index 05c53179a..38e4e28c7 100644 --- a/crates/oxc_mangler/src/lib.rs +++ b/crates/oxc_mangler/src/lib.rs @@ -184,6 +184,7 @@ impl Mangler { // Stores the lived scope ids for each slot. Keyed by slot number. let mut slot_liveness: std::vec::Vec = vec![]; + let mut tmp_bindings = std::vec::Vec::with_capacity(100); let mut reusable_slots = std::vec::Vec::new(); // Walk down the scope tree and assign a slot number for each symbol. @@ -217,8 +218,12 @@ impl Mangler { } // Sort `bindings` in declaration order. - let sorted_bindings = bindings.values().copied().sorted_unstable(); - for (symbol_id, assigned_slot) in sorted_bindings.zip(reusable_slots.iter().copied()) { + tmp_bindings.clear(); + tmp_bindings.extend(bindings.values().copied()); + tmp_bindings.sort_unstable(); + for (&symbol_id, assigned_slot) in + tmp_bindings.iter().zip(reusable_slots.iter().copied()) + { slots[symbol_id.index()] = assigned_slot; // If the symbol is declared by `var`, then it can be hoisted to