Rollup merge of #50365 - nnethercote:nearest_common_ancestor-two-vecs, r=nikomatsakis

Use two vectors in nearest_common_ancestor.

When looking at any scope in scope chain A, we only need to look for
matches among scopes previously seen in scope chain B, and vice versa.
This halves the number of "seen before?" comparisons, speeding up some
runs of style-servo, clap-rs, and syn by 1--2%.

Thanks to @kirillkh for the suggestion.

r? @nikomatsakis
This commit is contained in:
kennytm 2018-05-03 16:11:31 +08:00
commit fd4bf23783
No known key found for this signature in database
GPG Key ID: FEF6C8051D0E013C

View File

@ -690,21 +690,22 @@ impl<'tcx> ScopeTree {
// the start. So this algorithm is faster.
let mut ma = Some(scope_a);
let mut mb = Some(scope_b);
let mut seen: SmallVec<[Scope; 32]> = SmallVec::new();
let mut seen_a: SmallVec<[Scope; 32]> = SmallVec::new();
let mut seen_b: SmallVec<[Scope; 32]> = SmallVec::new();
loop {
if let Some(a) = ma {
if seen.iter().position(|s| *s == a).is_some() {
if seen_b.iter().position(|s| *s == a).is_some() {
return a;
}
seen.push(a);
seen_a.push(a);
ma = self.parent_map.get(&a).map(|s| *s);
}
if let Some(b) = mb {
if seen.iter().position(|s| *s == b).is_some() {
if seen_a.iter().position(|s| *s == b).is_some() {
return b;
}
seen.push(b);
seen_b.push(b);
mb = self.parent_map.get(&b).map(|s| *s);
}