-
Notifications
You must be signed in to change notification settings - Fork 20
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
Optimised extend #127
base: main
Are you sure you want to change the base?
Optimised extend #127
Conversation
🚀 Deployed on https://65059694ca32910d0ff42051--ringbuffer.netlify.app |
src/ringbuffer_trait.rs
Outdated
/// | ||
/// Depending on the RingBuffer implementation, may be faster than inserting items in a loop | ||
/// | ||
/// Note that this function is same as [`extend`] except that it is |
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 this actually specialized now or will it 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.
in constgeneric yes
src/ringbuffer_trait.rs
Outdated
where | ||
T: Default, | ||
where | ||
T: Default, |
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.
Rustfmt?
src/with_const_generics.rs
Outdated
{ | ||
#[allow(clippy::let_unit_value)] | ||
let _ = Self::ERROR_CAPACITY_IS_NOT_ALLOWED_TO_BE_ZERO; | ||
let _ = Self::ERROR_CAPACITY_IS_NOT_ALLOWED_TO_BE_ZERO; |
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 seems weird?
src/with_const_generics.rs
Outdated
@@ -418,6 +634,94 @@ mod tests { | |||
} | |||
} | |||
|
|||
struct WeirdIterator<T: IntoIterator>(<T as IntoIterator>::IntoIter, SizeHint); |
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.
Weirderator
All improvements are over a baseline of extend-by-push Batch Size = 1
Batch size = 32
Batch size = 256
Batch size = 1024
Binary search to a good batch Size; Batch size = 64
Batch size = 16
Batch size = 30
|
Although surprising to me, a batch size of 30 seems to work very well for large extends when the buffer does not start out empty. This feature is now behind a feature flag, since technically it's not 100% tested but it seems to perform very well in all tests I could throw at it. |
7568202
to
cf0437d
Compare
// Safety: clear above | ||
unsafe { self.finish_iter::<BATCH_SIZE>(iter) }; | ||
} else if self.is_empty() { | ||
self.clear(); |
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 think you can move this into finish_iter
and make it safe. Maybe rename it to new_from_iter
or something.
self.clear(); | ||
|
||
// Safety: clear above | ||
unsafe { self.finish_iter::<BATCH_SIZE>(iter) }; |
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.
Why is this not extend_batched_internal
?
// repeat until we find an empty batch | ||
loop { | ||
// fill up a batch | ||
let how_full = Self::fill_batch(&mut batch, &mut other); |
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 think the code might be simpler if you fill the batch with min(BATCH_SIZE, CAP - len)
instead. Then you never have to split the batch up and stuff.
If I understand correctly, finish_iter
is necessary because you need the writeptr not to be equal to readptr or something? Maybe if you do the min
thing, that might not be necessary? In any case, might be nice to document why and in what cases you need finish_iter
.
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.
No wait, I mean min(BATCH_SIZE, CAP - mod(writeptr, CAP))
I think. Whatever the number is of elements that fit until the end of the allocated space. So you don't have to split.
#123 @codehobbyist06
Closes #124