Skip to content

Commit 1419260

Browse files
committed
Avoid SmallVec::collect() in SubstsRef::super_fold_with().
This commit reduces instruction counts for several benchmarks by up to 5%.
1 parent 06c6894 commit 1419260

File tree

1 file changed

+35
-8
lines changed

1 file changed

+35
-8
lines changed

src/librustc/ty/subst.rs

+35-8
Original file line numberDiff line numberDiff line change
@@ -383,14 +383,41 @@ impl<'a, 'tcx> InternalSubsts<'tcx> {
383383

384384
impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> {
385385
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
386-
let params: SmallVec<[_; 8]> = self.iter().map(|k| k.fold_with(folder)).collect();
387-
388-
// If folding doesn't change the substs, it's faster to avoid
389-
// calling `mk_substs` and instead reuse the existing substs.
390-
if params[..] == self[..] {
391-
self
392-
} else {
393-
folder.tcx().intern_substs(&params)
386+
// This code is hot enough that it's worth specializing for the most
387+
// common length lists, to avoid the overhead of `SmallVec` creation.
388+
// The match arms are in order of frequency. The 1, 2, and 0 cases are
389+
// typically hit in 90--99.99% of cases. When folding doesn't change
390+
// the substs, it's faster to reuse the existing substs rather than
391+
// calling `intern_substs`.
392+
match self.len() {
393+
1 => {
394+
let param0 = self[0].fold_with(folder);
395+
if param0 == self[0] {
396+
self
397+
} else {
398+
folder.tcx().intern_substs(&[param0])
399+
}
400+
}
401+
2 => {
402+
let param0 = self[0].fold_with(folder);
403+
let param1 = self[1].fold_with(folder);
404+
if param0 == self[0] && param1 == self[1] {
405+
self
406+
} else {
407+
folder.tcx().intern_substs(&[param0, param1])
408+
}
409+
}
410+
0 => {
411+
self
412+
}
413+
_ => {
414+
let params: SmallVec<[_; 8]> = self.iter().map(|k| k.fold_with(folder)).collect();
415+
if params[..] == self[..] {
416+
self
417+
} else {
418+
folder.tcx().intern_substs(&params)
419+
}
420+
}
394421
}
395422
}
396423

0 commit comments

Comments
 (0)