flip the order of loops to make lookups much faster

This commit is contained in:
Folkert 2022-04-30 12:27:50 +02:00
parent a78aff0f2f
commit c1d9c63e37
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
3 changed files with 28 additions and 23 deletions

View file

@ -431,14 +431,10 @@ impl ScopedIdentIds {
}
fn has_in_scope(&self, ident: &Ident) -> Option<(Symbol, Region)> {
for index in self.in_scope.iter_ones() {
if let Some((ident_id, string)) = self.ident_ids.get_name_at_index(index) {
if string == ident.as_str() {
return Some((
Symbol::new(self.home, ident_id),
self.regions[ident_id.index()],
));
}
for ident_id in self.ident_ids.get_id_many(ident) {
let index = ident_id.index();
if self.in_scope[index] {
return Some((Symbol::new(self.home, ident_id), self.regions[index]));
}
}

View file

@ -86,11 +86,19 @@ impl SmallStringInterner {
#[inline(always)]
pub fn find_index(&self, string: &str) -> Option<usize> {
self.find_indices(string).next()
}
#[inline(always)]
pub fn find_indices<'a>(&'a self, string: &'a str) -> impl Iterator<Item = usize> + 'a {
let target_length = string.len() as u16;
// there can be gaps in the parts of the string that we use (because of updates)
// hence we can't just sum the lengths we've seen so far to get the next offset
for (index, length) in self.lengths.iter().enumerate() {
self.lengths
.iter()
.enumerate()
.filter_map(move |(index, length)| {
if *length == target_length {
let offset = self.offsets[index];
let slice = &self.buffer[offset as usize..][..*length as usize];
@ -99,9 +107,9 @@ impl SmallStringInterner {
return Some(index);
}
}
}
None
})
}
fn get(&self, index: usize) -> &str {

View file

@ -580,14 +580,15 @@ impl IdentIds {
.map(|i| IdentId(i as u32))
}
pub fn get_name(&self, id: IdentId) -> Option<&str> {
self.interner.try_get(id.0 as usize)
#[inline(always)]
pub fn get_id_many<'a>(&'a self, ident_name: &'a Ident) -> impl Iterator<Item = IdentId> + 'a {
self.interner
.find_indices(ident_name.as_str())
.map(|i| IdentId(i as u32))
}
pub fn get_name_at_index(&self, index: usize) -> Option<(IdentId, &str)> {
self.interner
.try_get(index)
.map(|v| (IdentId(index as u32), v))
pub fn get_name(&self, id: IdentId) -> Option<&str> {
self.interner.try_get(id.0 as usize)
}
pub fn get_name_str_res(&self, ident_id: IdentId) -> ModuleResult<&str> {