Skip to content

Commit

Permalink
Iterate over the smaller list
Browse files Browse the repository at this point in the history
If there are two lists of different sizes,
iterating over the smaller list and then
looking up in the larger list is cheaper
than vice versa, because lookups scale
sublinearly.
  • Loading branch information
est31 committed Oct 24, 2020
1 parent 4d247ad commit a21c2eb
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 0 deletions.
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/ty/mod.rs
Expand Up @@ -265,6 +265,10 @@ impl<'tcx> AssociatedItems<'tcx> {
self.items.iter().map(|(_, v)| *v)
}

pub fn len(&self) -> usize {
self.items.len()
}

/// Returns an iterator over all associated items with the given name, ignoring hygiene.
pub fn filter_by_name_unhygienic(
&self,
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs
Expand Up @@ -22,6 +22,14 @@ impl InherentOverlapChecker<'tcx> {
let impl_items1 = self.tcx.associated_items(impl1);
let impl_items2 = self.tcx.associated_items(impl2);

let mut impl_items1 = &impl_items1;
let mut impl_items2 = &impl_items2;

// Performance optimization: iterate over the smaller list
if impl_items1.len() > impl_items2.len() {
std::mem::swap(&mut impl_items1, &mut impl_items2);
}

for item1 in impl_items1.in_definition_order() {
let collision = impl_items2.filter_by_name_unhygienic(item1.ident.name).any(|item2| {
// Symbols and namespace match, compare hygienically.
Expand Down

0 comments on commit a21c2eb

Please sign in to comment.