From ac77c87cec8179c198d3b2f71e5f91dcfcddaff0 Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Fri, 18 Oct 2024 15:43:47 +0000 Subject: [PATCH] perf(traverse): optimize `TraverseScoping::generate_uid_name` (#6663) Tiny optimization. Move initializing `self.uid_names` to just before `self.uid_names.as_mut().unwrap()` so compiler can see that the `unwrap` is infallible and elide it, even if `get_uid_names` isn't inlined. --- crates/oxc_traverse/src/context/scoping.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/crates/oxc_traverse/src/context/scoping.rs b/crates/oxc_traverse/src/context/scoping.rs index f446f4d60d73a..415a672dd2d46 100644 --- a/crates/oxc_traverse/src/context/scoping.rs +++ b/crates/oxc_traverse/src/context/scoping.rs @@ -180,7 +180,7 @@ impl TraverseScoping { /// /// This function is fairly expensive, because it aims to replicate Babel's output. /// - /// `init_uid_names` iterates through every single binding and unresolved reference in the entire AST, + /// `get_uid_names` iterates through every single binding and unresolved reference in the entire AST, /// and builds a hashset of symbols which could clash with UIDs. /// Once that's built, it's cached, but `find_uid_name` still has to do at least one hashset lookup, /// and a hashset insert. If the first name tried is already in use, it will do another hashset lookup, @@ -218,7 +218,7 @@ impl TraverseScoping { pub fn generate_uid_name(&mut self, name: &str) -> CompactStr { // If `uid_names` is not already populated, initialize it if self.uid_names.is_none() { - self.init_uid_names(); + self.uid_names = Some(self.get_uid_names()); } let uid_names = self.uid_names.as_mut().unwrap(); @@ -406,16 +406,15 @@ impl TraverseScoping { self.current_scope_id = scope_id; } - /// Initialize `uid_names`. + /// Get `uid_names`. /// /// Iterate through all symbols and unresolved references in AST and identify any var names /// which could clash with UIDs (start with `_`). Build a hash set containing them. /// - /// Once this map is created, generating a UID is a relatively quick operation, rather than + /// Once this set is created, generating a UID is a relatively quick operation, rather than /// iterating over all symbols and unresolved references every time generate a UID. - fn init_uid_names(&mut self) { - let uid_names = self - .scopes + fn get_uid_names(&mut self) -> FxHashSet { + self.scopes .root_unresolved_references() .keys() .chain(self.symbols.names.iter()) @@ -426,8 +425,7 @@ impl TraverseScoping { None } }) - .collect(); - self.uid_names = Some(uid_names); + .collect() } }