Skip to content

Commit

Permalink
Auto merge of #92566 - the8472:inline-tra, r=m-ou-se
Browse files Browse the repository at this point in the history
Inline `__iterator_get_unchecked` for some iterator adapters.

This aligns the inline attributes of existing `__iterator_get_unchecked` with those of `next()` on adapters that have both.

It improves the performance of iterators using unchecked access when building in incremental mode (due to the larger CGU count?). It might negatively affect incremental compile times for better runtime results, but considering that the equivalent `next()` implementations also are `#[inline]` and usually are more complex this should be ok.

```
./x.py bench library/core -i --stage 0 --test-args bench_trusted_random_access

OLD: 119,172 ns/iter
NEW:  17,714 ns/iter
```
  • Loading branch information
bors committed May 2, 2022
2 parents bed05e9 + a68a5d2 commit 3d0ac7e
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 0 deletions.
24 changes: 24 additions & 0 deletions library/core/benches/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,3 +367,27 @@ fn bench_partial_cmp(b: &mut Bencher) {
fn bench_lt(b: &mut Bencher) {
b.iter(|| (0..100000).map(black_box).lt((0..100000).map(black_box)))
}

#[bench]
fn bench_trusted_random_access_adapters(b: &mut Bencher) {
let vec1: Vec<_> = (0usize..100000).collect();
let vec2 = black_box(vec1.clone());
b.iter(|| {
let mut iter = vec1
.iter()
.copied()
.enumerate()
.map(|(idx, e)| idx.wrapping_add(e))
.zip(vec2.iter().copied())
.map(|(a, b)| a.wrapping_add(b))
.fuse();
let mut acc: usize = 0;
let size = iter.size();
for i in 0..size {
// SAFETY: TRA requirements are satisfied by 0..size iteration and then dropping the
// iterator.
acc = acc.wrapping_add(unsafe { iter.__iterator_get_unchecked(i) });
}
acc
})
}
1 change: 1 addition & 0 deletions library/core/benches/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#![feature(flt2dec)]
#![feature(int_log)]
#![feature(test)]
#![feature(trusted_random_access)]

extern crate test;

Expand Down
1 change: 1 addition & 0 deletions library/core/src/iter/adapters/enumerate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ where

#[rustc_inherit_overflow_checks]
#[doc(hidden)]
#[inline]
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
where
Self: TrustedRandomAccessNoCoerce,
Expand Down
1 change: 1 addition & 0 deletions library/core/src/iter/adapters/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ where
}

#[doc(hidden)]
#[inline]
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> B
where
Self: TrustedRandomAccessNoCoerce,
Expand Down
2 changes: 2 additions & 0 deletions library/core/src/iter/adapters/zip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,7 @@ pub unsafe trait TrustedRandomAccessNoCoerce: Sized {
///
/// Same requirements calling `get_unchecked` directly.
#[doc(hidden)]
#[inline]
pub(in crate::iter::adapters) unsafe fn try_get_unchecked<I>(it: &mut I, idx: usize) -> I::Item
where
I: Iterator,
Expand All @@ -576,6 +577,7 @@ unsafe impl<I: Iterator> SpecTrustedRandomAccess for I {
}

unsafe impl<I: Iterator + TrustedRandomAccessNoCoerce> SpecTrustedRandomAccess for I {
#[inline]
unsafe fn try_get_unchecked(&mut self, index: usize) -> Self::Item {
// SAFETY: the caller must uphold the contract for
// `Iterator::__iterator_get_unchecked`.
Expand Down
1 change: 1 addition & 0 deletions library/core/src/slice/iter/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ macro_rules! iterator {
}

#[doc(hidden)]
#[inline]
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
// SAFETY: the caller must guarantee that `i` is in bounds of
// the underlying slice, so `i` cannot overflow an `isize`, and
Expand Down

0 comments on commit 3d0ac7e

Please sign in to comment.