mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-29 00:46:32 +00:00
rollup merge of #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) ````
This commit is contained in:
commit
1d921f557d
@ -724,11 +724,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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user