-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Optimize core::Zip::next_back() #147740
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Optimize core::Zip::next_back() #147740
Conversation
Just realised that if |
/// Calls to `self.nth_back(n)` are counted as `n + 1` calls to `self.next_back()`, and | ||
/// calls to `self.advance_back_by(n)` as `n` calls. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this is true, I'm not sure what it's doing here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Point 3 of TrustedRandomAccess
's safety requirements says (paraphrased) that you can't use next_back()
to move the tail to an element that has already been returned by __iterator_get_unchecked()
. This extends that requirement to calls to nth_back()
and advance_back_by()
.
iter4.next_back(); | ||
assert_eq!(&log.take(), &[0, 1, 1, 1, 0, 1]); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This tests for the ordering of calls to the constituent iterators of a Zip, but I don't think that ordering is specified, nor do I think it should be...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't want to break anything, but if the call order is unspecified then we can get cleaner code here, and faster code for nth()
and nth_back()
, so I've removed the test.
Fix #147704 by replacing
next_back()
calls in a loop with one call tonth_back()
.This also modifies the safety conditions for the (unstable)
TrustedRandomAccessNoCoerce
trait by allowing calls toself.nth_back(n)
andself.advance_back_by(n)
after a call toself.__iterator_get_unchecked()
provided they don't move the tail too far.A grep found that the
TrustedRandomAccessNoCoerce
trait is implemented by the following structs:alloc::collections::vec_deque::{Iter<T>, IterMut<T>}
alloc::vec::IntoIter<T>
core::array::IntoIter<T, N>
core::char::{CaseMappingIter, ToLowercase, ToUppercase}
core::iter::{Cloned<I>, Copied<I>, Enumerate<I>, Fused<I>, Map<I, F>, Skip<I>, Zip<A, B>}
core::ops::Range<_>
core::range::IterRange<_>
core::slice::{Chunks<T>, ChunksExact<T>, ChunksExactMut<T>, ChunksMut<T>, Iter<T>, IterMut<T>, RChunks<T>, RChunksExact<T>, RChunksExactMut<T>, RChunksMut<T>, Windows<T>}
core::str::Bytes
I believe this is sound, as the implementations of
advance_back_by()
for the above do essentially the same thing as repeatednext_back()
calls, but better optimized.If there is an issue, a partial fix could be implemented by using the new version as the default and specializing
TrustedRandomAccessNoCoerce
to use the current implementation.