-
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
AllocRingBuffer
: separate size from capacity and remove power of 2 types
#114
Conversation
src/with_alloc/alloc_ringbuffer.rs
Outdated
pub struct AllocRingBuffer<T> { | ||
buf: *mut T, | ||
size: usize, | ||
capacity: usize, | ||
readptr: usize, | ||
writeptr: usize, | ||
mode: PhantomData<SIZE>, | ||
} |
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 added a size
field here and removed mode
.
1867655
to
4b0613e
Compare
I measure 57% speedup on non-powers of 2 and +1.2% (likely noise) on powers of two. As well as cleaning up the API a ton, I think this is a good change. |
src/with_alloc/alloc_ringbuffer.rs
Outdated
@@ -408,22 +296,25 @@ impl<T> AllocRingBuffer<T, PowerOfTwo> { | |||
/// Panics when capacity is zero or not a power of two |
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.
Docs out of date here (and probably in other places too)
4951949
to
169a34a
Compare
and THAT'S why we have MIRI in the CI lol |
Memory leaks are safe, I don't see any issues here |
I've already talked about this with @jonay2000, but to reiterate: this is just an idea. Your current implementation is fine and feel free to just close this.
This patch removes the distinction between
PowerOfTwo
andNonPowerOfTwo
and gives a performance improvement of ~30% to the non power of 2 benchmarks, while making powers of 2 10% slower.This is achieved by adding a field called
size
toAllocRingBuffer
. Thesize
is always set to the next power of 2 of thecapacity
. The idea is that thecapacity
is not the size of the allocation. Instead, an allocation ofsize
is made, so we always mask with the size. But the capacity still forms a hard limit on the length of the buffer.The upsides are:
with_capacity
now always succeeds for a non-zero capacity. This is (in my opinion) a more predictable behaviour and there is less opportunity to accidentally misuse the library.PowerOfTwo
,NonPowerOfTwo
andRingbufferSize
are all removedwith_capacity_non_power_of_two
is removed (because it's now equivalent towith_capacity
)AllocRingBuffer
only has one type parameter, which also simplifies a lot of method signatures throughout the code base.The downsides are:
2^x + 1
then the buffer will be almost twice as big as strictly necessary.Summary of benchmarks:
Full benchmarks (click to open)
Because this diff has a lot of type signature changes I'll add comments to point you to the important bits.