diff options
| author | kennytm <kennytm@gmail.com> | 2018-05-23 00:26:15 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-05-23 00:26:15 +0800 |
| commit | 5b67b13d1e3eb657e94bcf974579c576bbbab873 (patch) | |
| tree | 3dabe44eeff93e9567eb497e5cc6ecd89314ea45 | |
| parent | bc76e8b029c83f115b369c921d55077e6a5a2ea8 (diff) | |
| parent | 2ff632484cd8c2e3b123fbf52d9dd39b54a94505 (diff) | |
| download | rust-5b67b13d1e3eb657e94bcf974579c576bbbab873.tar.gz rust-5b67b13d1e3eb657e94bcf974579c576bbbab873.zip | |
Rollup merge of #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%.
| -rw-r--r-- | src/librustc/traits/select.rs | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index c3b5b8e6fb3..7a52a5cbf5a 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -3356,13 +3356,28 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { predicate: predicate.value })) }).collect(); + // We are performing deduplication here to avoid exponential blowups // (#38528) from happening, but the real cause of the duplication is // unknown. What we know is that the deduplication avoids exponential - // amount of predicates being propogated when processing deeply nested + // amount of predicates being propagated when processing deeply nested // types. - let mut seen = FxHashSet(); - predicates.retain(|i| seen.insert(i.clone())); + // + // This code is hot enough that it's worth avoiding the allocation + // required for the FxHashSet when possible. Special-casing lengths 0, + // 1 and 2 covers roughly 75--80% of the cases. + if predicates.len() <= 1 { + // No possibility of duplicates. + } else if predicates.len() == 2 { + // Only two elements. Drop the second if they are equal. + if predicates[0] == predicates[1] { + predicates.truncate(1); + } + } else { + // Three or more elements. Use a general deduplication process. + let mut seen = FxHashSet(); + predicates.retain(|i| seen.insert(i.clone())); + } self.infcx().plug_leaks(skol_map, snapshot, predicates) } } |
