Skip to content

Commit 5b67b13

Browse files
authored
Rollup merge of rust-lang#50932 - nnethercote:seen-Predicates, r=eddyb
Optimize seen Predicate filtering. This speeds up a few rustc-perf benchmark runs, most notably ones involving 'coercions', the best by 2%.
2 parents bc76e8b + 2ff6324 commit 5b67b13

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

src/librustc/traits/select.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -3356,13 +3356,28 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
33563356
predicate: predicate.value
33573357
}))
33583358
}).collect();
3359+
33593360
// We are performing deduplication here to avoid exponential blowups
33603361
// (#38528) from happening, but the real cause of the duplication is
33613362
// unknown. What we know is that the deduplication avoids exponential
3362-
// amount of predicates being propogated when processing deeply nested
3363+
// amount of predicates being propagated when processing deeply nested
33633364
// types.
3364-
let mut seen = FxHashSet();
3365-
predicates.retain(|i| seen.insert(i.clone()));
3365+
//
3366+
// This code is hot enough that it's worth avoiding the allocation
3367+
// required for the FxHashSet when possible. Special-casing lengths 0,
3368+
// 1 and 2 covers roughly 75--80% of the cases.
3369+
if predicates.len() <= 1 {
3370+
// No possibility of duplicates.
3371+
} else if predicates.len() == 2 {
3372+
// Only two elements. Drop the second if they are equal.
3373+
if predicates[0] == predicates[1] {
3374+
predicates.truncate(1);
3375+
}
3376+
} else {
3377+
// Three or more elements. Use a general deduplication process.
3378+
let mut seen = FxHashSet();
3379+
predicates.retain(|i| seen.insert(i.clone()));
3380+
}
33663381
self.infcx().plug_leaks(skol_map, snapshot, predicates)
33673382
}
33683383
}

0 commit comments

Comments
 (0)