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.
This commit is contained in:
overlookmotel 2024-10-18 15:43:47 +00:00
parent 9d43a1124d
commit ac77c87cec

View file

@ -180,7 +180,7 @@ impl TraverseScoping {
/// ///
/// This function is fairly expensive, because it aims to replicate Babel's output. /// 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. /// 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, /// 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, /// 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 { pub fn generate_uid_name(&mut self, name: &str) -> CompactStr {
// If `uid_names` is not already populated, initialize it // If `uid_names` is not already populated, initialize it
if self.uid_names.is_none() { 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(); let uid_names = self.uid_names.as_mut().unwrap();
@ -406,16 +406,15 @@ impl TraverseScoping {
self.current_scope_id = scope_id; 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 /// 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. /// 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. /// iterating over all symbols and unresolved references every time generate a UID.
fn init_uid_names(&mut self) { fn get_uid_names(&mut self) -> FxHashSet<CompactStr> {
let uid_names = self self.scopes
.scopes
.root_unresolved_references() .root_unresolved_references()
.keys() .keys()
.chain(self.symbols.names.iter()) .chain(self.symbols.names.iter())
@ -426,8 +425,7 @@ impl TraverseScoping {
None None
} }
}) })
.collect(); .collect()
self.uid_names = Some(uid_names);
} }
} }