From 69352d74c28176087829c82c31c1a8672735f8a1 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Tue, 29 Jun 2021 23:22:54 +0800 Subject: [PATCH] Optimize Scope layout. --- src/ast.rs | 2 +- src/scope.rs | 30 ++++++++++++++---------------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index e7c92ae8..87af9821 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -2206,7 +2206,7 @@ mod tests { 96 } ); - assert_eq!(size_of::(), 160); + assert_eq!(size_of::(), 464); assert_eq!(size_of::(), 56); assert_eq!( size_of::(), diff --git a/src/scope.rs b/src/scope.rs index 2fe9bcfb..9fa87088 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -49,14 +49,14 @@ const SCOPE_ENTRIES_INLINED: usize = 8; // look up a variable. Variable lookup is usually via direct indexing, by-passing the name altogether. // // Since [`Dynamic`] is reasonably small, packing it tightly improves cache locality when variables are accessed. -// -// The alias is `Box`'ed because it occurs infrequently. #[derive(Debug, Clone, Hash)] pub struct Scope<'a> { /// Current value of the entry. values: smallvec::SmallVec<[Dynamic; SCOPE_ENTRIES_INLINED]>, /// (Name, aliases) of the entry. - names: Vec<(Cow<'a, str>, Option>>)>, + names: smallvec::SmallVec< + [(Cow<'a, str>, Option>>); SCOPE_ENTRIES_INLINED], + >, } impl Default for Scope<'_> { @@ -253,7 +253,7 @@ impl<'a> Scope<'a> { access: AccessMode, mut value: Dynamic, ) -> &mut Self { - self.names.push((name.into(), None)); + self.names.push((name.into(), Default::default())); value.set_access_mode(access); self.values.push(value.into()); self @@ -436,20 +436,18 @@ impl<'a> Scope<'a> { #[cfg(not(feature = "no_module"))] #[inline(always)] pub(crate) fn add_entry_alias(&mut self, index: usize, alias: Identifier) -> &mut Self { - let entry = self + let (_, aliases) = self .names .get_mut(index) .expect("never fails unless the index is out of bounds"); - if entry.1.is_none() { - // Initialize the alias list if it is empty. - entry.1 = Some(Default::default()); - } - let list = entry - .1 - .as_mut() - .expect("never fails because the list is initialized"); - if !list.iter().any(|a| a == &alias) { - list.push(alias); + match aliases { + None => { + let mut list = StaticVec::new(); + list.push(alias); + *aliases = Some(list.into()); + } + Some(aliases) if !aliases.iter().any(|a| a == &alias) => aliases.push(alias), + Some(_) => (), } self } @@ -534,7 +532,7 @@ impl<'a, K: Into>> Extend<(K, Dynamic)> for Scope<'a> { #[inline(always)] fn extend>(&mut self, iter: T) { iter.into_iter().for_each(|(name, value)| { - self.names.push((name.into(), None)); + self.names.push((name.into(), Default::default())); self.values.push(value); }); }