Skip to content

Commit

Permalink
Optimize rposition
Browse files Browse the repository at this point in the history
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)
````
  • Loading branch information
dotdash committed Feb 3, 2015
1 parent 3d072a1 commit 9a17f62
Showing 1 changed file with 4 additions and 3 deletions.
7 changes: 4 additions & 3 deletions src/libcore/iter.rs
Expand Up @@ -723,11 +723,12 @@ pub trait IteratorExt: Iterator + Sized {
P: FnMut(Self::Item) -> bool,
Self: ExactSizeIterator + DoubleEndedIterator
{
let len = self.len();
for i in (0..len).rev() {
if predicate(self.next_back().expect("rposition: incorrect ExactSizeIterator")) {
let mut i = self.len() - 1;
while let Some(v) = self.next_back() {
if predicate(v) {
return Some(i);
}
i -= 1;
}
None
}
Expand Down

0 comments on commit 9a17f62

Please sign in to comment.