Skip to content

Commit 4153fa8

Browse files
committed
Auto merge of rust-lang#80715 - JulianKnodt:skip_opt, r=nagisa
Change branching in `iter.skip()` Optimize branching in `Skip`, which was brought up in rust-lang#80416. This assumes that if `next` is called, it's likely that there will be more calls to `next`, and the branch for skip will only be hit once thus it's unlikely to take that path. Even w/o the `unlikely` intrinsic, it compiles more efficiently, I believe because the path where `next` is called is always taken. It should be noted there are very few places in the compiler where `Skip` is used, so probably won't have a noticeable perf impact. [New impl](https://godbolt.org/z/85rdj4) [Old impl](https://godbolt.org/z/Wc74rh) [Some additional asm examples](https://godbolt.org/z/feKzoz) although they really don't have a ton of difference between them.
2 parents 1986b58 + e5094a2 commit 4153fa8

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

library/core/benches/iter.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,29 @@ bench_sums! {
276276
bench_sums! {
277277
bench_cycle_take_sum,
278278
bench_cycle_take_ref_sum,
279-
(0i64..10000).cycle().take(1000000)
279+
(0..10000).cycle().take(1000000)
280+
}
281+
282+
bench_sums! {
283+
bench_cycle_skip_take_sum,
284+
bench_cycle_skip_take_ref_sum,
285+
(0..100000).cycle().skip(1000000).take(1000000)
286+
}
287+
288+
bench_sums! {
289+
bench_cycle_take_skip_sum,
290+
bench_cycle_take_skip_ref_sum,
291+
(0..100000).cycle().take(1000000).skip(100000)
292+
}
293+
294+
bench_sums! {
295+
bench_skip_cycle_skip_zip_add_sum,
296+
bench_skip_cycle_skip_zip_add_ref_sum,
297+
(0..100000).skip(100).cycle().skip(100)
298+
.zip((0..100000).cycle().skip(10))
299+
.map(|(a,b)| a+b)
300+
.skip(100000)
301+
.take(1000000)
280302
}
281303

282304
// Checks whether Skip<Zip<A,B>> is as fast as Zip<Skip<A>, Skip<B>>, from

library/core/src/iter/adapters/skip.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::intrinsics::unlikely;
12
use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable};
23
use crate::ops::{ControlFlow, Try};
34

@@ -31,13 +32,10 @@ where
3132

3233
#[inline]
3334
fn next(&mut self) -> Option<I::Item> {
34-
if self.n == 0 {
35-
self.iter.next()
36-
} else {
37-
let old_n = self.n;
38-
self.n = 0;
39-
self.iter.nth(old_n)
35+
if unlikely(self.n > 0) {
36+
self.iter.nth(crate::mem::take(&mut self.n) - 1);
4037
}
38+
self.iter.next()
4139
}
4240

4341
#[inline]

0 commit comments

Comments
 (0)