-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Add Iterator::array_chunks method #87776
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @joshtriplett (or someone else) soon. Please see the contribution instructions for more information. |
self.init = 0; | ||
// SAFETY: This is safe: `MaybeUninit<T>` is guaranteed to have the same layout | ||
// as `T` and the entire array has just been initialized. | ||
unsafe { Some(mem::transmute_copy(&self.buffer)) } |
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.
Reusing memory (going through self
) and then transmute-copying it to return it seems like it would optimize badly. Benchmarks exercising this adapter together with a for-in loop as baseline would help.
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 have added some benchmarks comparing it to looping over a mapped iterator producing arrays and the ArrayChunks
iterator for slices.
test iter::bench_array_map ... bench: 437,783 ns/iter (+/- 13,664)
test iter::bench_iter_array_chunks ... bench: 2,684,281 ns/iter (+/- 206,116)
test iter::bench_iter_array_chunks_fold ... bench: 2,217,095 ns/iter (+/- 127,330)
test iter::bench_slice_array_chunks ... bench: 335,405 ns/iter (+/- 99,203)
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
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 managed to improve the performance by quite a bit. Now it only takes twice as long as passing an array through an iterator pipeline. I also removed the transmute_copy
(slight increase in performance).
test iter::bench_array_map ... bench: 412,536 ns/iter (+/- 19,784)
test iter::bench_iter_array_chunks_fold ... bench: 856,663 ns/iter (+/- 67,238)
test iter::bench_iter_array_chunks_loop ... bench: 1,678,215 ns/iter (+/- 78,573)
test iter::bench_iter_array_chunks_ref_fold ... bench: 1,511,018 ns/iter (+/- 86,835)
test iter::bench_slice_array_chunks ... bench: 337,726 ns/iter (+/- 83,062)
/// [`array_rchunks`]: Iterator::array_rchunks | ||
#[unstable(feature = "iter_array_chunks", issue = "none")] | ||
#[derive(Debug)] | ||
pub struct ArrayRChunks<I: DoubleEndedIterator, const N: usize> { |
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.
Is array_rchunks
actually redundant? Seems to me it's distinct from both .rev().array_chunks()
(because the elements within the chunks are in the original order) and .array_chunks().rev()
(when .remainder().len() != 0
).
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.
It's mostly redundant with the exception of the remainder its equivalent to:
.rev().array_chunks().map(|mut arr| { arr.reverse(); arr})
If it still seems useful, I can re-include it. Also ArrayChunks
doesn't currently implement DoubleEndedIterator
, although it could but it might produce surprising results if advanced from both directions. If it were implemented though, I think it could produce the same results as ArrayRChunks
including the remainder.
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 have now added a DoubleEndedIterator
implementation that seems to produce the same results array_rchunks
would. It's not quite as efficient as it could be though, just to keep complexity down and share more code with the forward implementation.
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 starts to look like it's containing half of an implementation of the fabled ArrayVec
, as the FIXME notes this also contains some redundancy with the some array
code.
I have made |
Yeah, |
Are there any other changes this needs? Should I open a tracking issue for this? |
|
☔ The latest upstream changes (presumably #89703) made this pull request unmergeable. Please resolve the merge conflicts. |
Was this closed due to issues with the code or just lack of time? That would be relevant if someone wants to pick it up. |
|
@the8472 It was a bit of both. I think someone else is working on a partial implementation of |
This adds an
array_chunks
(andarray_rchunks
) method to the iterator trait similar to the method with the same name on slices. Issue #81615 seems to indicate this would be useful.