Skip to content

Commit 1d921f5

Browse files
committed
rollup merge of rust-lang#21897: dotdash/rposition
The extra check caused by the expect() call can, in general, not be optimized away, because the length of the iterator is unknown at compile time, causing a noticable slow-down. Since the check only triggers if the element isn't actually found in the iterator, i.e. it isn't guaranteed to trigger for ill-behaved ExactSizeIterators, it seems reasonable to switch to an implementation that doesn't need the check and just always returns None if the value isn't found. Benchmark: ````rust let v: Vec<u8> = (0..1024*65).map(|_| 0).collect(); b.iter(|| { v.as_slice().iter().rposition(|&c| c == 1) }); ```` Before: ```` test rposition ... bench: 49939 ns/iter (+/- 23) ```` After: ```` test rposition ... bench: 33306 ns/iter (+/- 68) ````
2 parents 61b2f3a + 9a17f62 commit 1d921f5

File tree

1 file changed

+4
-3
lines changed

1 file changed

+4
-3
lines changed

src/libcore/iter.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -724,11 +724,12 @@ pub trait IteratorExt: Iterator + Sized {
724724
P: FnMut(Self::Item) -> bool,
725725
Self: ExactSizeIterator + DoubleEndedIterator
726726
{
727-
let len = self.len();
728-
for i in (0..len).rev() {
729-
if predicate(self.next_back().expect("rposition: incorrect ExactSizeIterator")) {
727+
let mut i = self.len() - 1;
728+
while let Some(v) = self.next_back() {
729+
if predicate(v) {
730730
return Some(i);
731731
}
732+
i -= 1;
732733
}
733734
None
734735
}

0 commit comments

Comments
 (0)