Skip to content

Commit 9a17f62

Browse files
committed
Optimize 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) ````
1 parent 3d072a1 commit 9a17f62

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
@@ -723,11 +723,12 @@ pub trait IteratorExt: Iterator + Sized {
723723
P: FnMut(Self::Item) -> bool,
724724
Self: ExactSizeIterator + DoubleEndedIterator
725725
{
726-
let len = self.len();
727-
for i in (0..len).rev() {
728-
if predicate(self.next_back().expect("rposition: incorrect ExactSizeIterator")) {
726+
let mut i = self.len() - 1;
727+
while let Some(v) = self.next_back() {
728+
if predicate(v) {
729729
return Some(i);
730730
}
731+
i -= 1;
731732
}
732733
None
733734
}

0 commit comments

Comments
 (0)