From 4b0613e0c9715304102d484f9647ede631e21e5d Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Fri, 9 Jun 2023 11:20:23 +0200 Subject: [PATCH 1/5] AllocRingBuffer: separate size from capacity and remove power of 2 distinction --- benches/bench.rs | 23 +-- src/lib.rs | 4 +- src/with_alloc/alloc_ringbuffer.rs | 247 ++++++++--------------------- src/with_alloc/vecdeque.rs | 5 +- src/with_const_generics.rs | 7 +- tests/conversions.rs | 2 +- 6 files changed, 74 insertions(+), 214 deletions(-) diff --git a/benches/bench.rs b/benches/bench.rs index aad03d3..1b13b85 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -73,7 +73,7 @@ macro_rules! generate_benches { (non_power_two, $c: tt, $rb: tt, $ty: tt, $fn: tt, $bmfunc: tt, $($i:tt),*) => { $( $c.bench_function(&format!("{} {} 1M capacity not power of two {}", stringify!($rb), stringify!($bmfunc), stringify!($i)), |b| $bmfunc(b, || { - $rb::<$ty, _>::$fn($i) + $rb::<$ty>::$fn($i) })); )* }; @@ -87,19 +87,6 @@ macro_rules! generate_benches { }; } -fn benchmark_non_power_of_two(b: &mut Bencher) { - b.iter(|| { - let mut rb = AllocRingBuffer::with_capacity_non_power_of_two(L); - - for i in 0..1_000_000 { - rb.push(i); - black_box(()); - } - - rb - }) -} - fn criterion_benchmark(c: &mut Criterion) { // TODO: Improve benchmarks // * What are representative operations @@ -111,7 +98,7 @@ fn criterion_benchmark(c: &mut Criterion) { c, AllocRingBuffer, i32, - with_capacity, + new, benchmark_push, 16, 1024, @@ -135,7 +122,7 @@ fn criterion_benchmark(c: &mut Criterion) { c, AllocRingBuffer, i32, - with_capacity, + new, benchmark_various, 16, 1024, @@ -159,7 +146,7 @@ fn criterion_benchmark(c: &mut Criterion) { c, AllocRingBuffer, i32, - with_capacity, + new, benchmark_push_dequeue, 16, 1024, @@ -183,7 +170,7 @@ fn criterion_benchmark(c: &mut Criterion) { c, AllocRingBuffer, i32, - with_capacity_non_power_of_two, + new, benchmark_various, 16, 17, diff --git a/src/lib.rs b/src/lib.rs index 37074a1..ae553dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,8 +26,6 @@ mod with_alloc; #[cfg(feature = "alloc")] pub use with_alloc::alloc_ringbuffer::AllocRingBuffer; #[cfg(feature = "alloc")] -pub use with_alloc::alloc_ringbuffer::{NonPowerOfTwo, PowerOfTwo, RingbufferSize}; -#[cfg(feature = "alloc")] pub use with_alloc::vecdeque::GrowableAllocRingBuffer; mod with_const_generics; @@ -1381,6 +1379,6 @@ mod tests { test_clone!(ConstGenericRingBuffer::<_, 4>::new()); test_clone!(GrowableAllocRingBuffer::<_>::new()); - test_clone!(AllocRingBuffer::<_, _>::new(4)); + test_clone!(AllocRingBuffer::<_>::new(4)); } } diff --git a/src/with_alloc/alloc_ringbuffer.rs b/src/with_alloc/alloc_ringbuffer.rs index df6f886..354d66f 100644 --- a/src/with_alloc/alloc_ringbuffer.rs +++ b/src/with_alloc/alloc_ringbuffer.rs @@ -7,60 +7,9 @@ use crate::ringbuffer_trait::{ extern crate alloc; // We need boxes, so depend on alloc -use crate::GrowableAllocRingBuffer; -use core::marker::PhantomData; +use crate::{mask, GrowableAllocRingBuffer}; use core::ptr; -#[derive(Debug, Copy, Clone)] -/// Represents that an alloc ringbuffer must have a size that's a power of two. -/// This means slightly more optimizations can be performed, but it is less flexible. -pub struct PowerOfTwo; - -#[derive(Debug, Copy, Clone)] -/// Represents that an alloc ringbuffer can have a size that's not a power of two. -/// This means slightly fewer optimizations can be performed, but it is more flexible. -pub struct NonPowerOfTwo; -mod private { - use crate::with_alloc::alloc_ringbuffer::{NonPowerOfTwo, PowerOfTwo}; - - pub trait Sealed {} - - impl Sealed for PowerOfTwo {} - impl Sealed for NonPowerOfTwo {} -} - -/// Sealed trait with two implementations that represent the kinds of sizes a ringbuffer can have -/// *[`NonPowerOfTwo`] -/// *[`PowerOfTwo`] -pub trait RingbufferSize: private::Sealed { - /// the mask function to use for wrapping indices in the ringbuffer - fn mask(cap: usize, index: usize) -> usize; - /// true in [`PowerOfTwo`], false in [`NonPowerOfTwo`] - fn must_be_power_of_two() -> bool; -} - -impl RingbufferSize for PowerOfTwo { - #[inline] - fn mask(cap: usize, index: usize) -> usize { - crate::mask(cap, index) - } - - fn must_be_power_of_two() -> bool { - true - } -} - -impl RingbufferSize for NonPowerOfTwo { - #[inline] - fn mask(cap: usize, index: usize) -> usize { - crate::mask_modulo(cap, index) - } - - fn must_be_power_of_two() -> bool { - false - } -} - /// The `AllocRingBuffer` is a `RingBuffer` which is based on a Vec. This means it allocates at runtime /// on the heap, and therefore needs the [`alloc`] crate. This struct and therefore the dependency on /// alloc can be disabled by disabling the `alloc` (default) feature. @@ -88,23 +37,23 @@ impl RingbufferSize for NonPowerOfTwo { /// assert_eq!(buffer.to_vec(), vec![42, 1]); /// ``` #[derive(Debug)] -pub struct AllocRingBuffer { +pub struct AllocRingBuffer { buf: *mut T, + size: usize, capacity: usize, readptr: usize, writeptr: usize, - mode: PhantomData, } -impl From<[T; N]> for AllocRingBuffer { +impl From<[T; N]> for AllocRingBuffer { fn from(value: [T; N]) -> Self { - let mut rb = Self::with_capacity_non_power_of_two(value.len()); + let mut rb = Self::new(value.len()); rb.extend(value.into_iter()); rb } } -impl From<&[T; N]> for AllocRingBuffer { +impl From<&[T; N]> for AllocRingBuffer { // the cast here is actually not trivial #[allow(trivial_casts)] fn from(value: &[T; N]) -> Self { @@ -112,85 +61,83 @@ impl From<&[T; N]> for AllocRingBuffer From<&[T]> for AllocRingBuffer { +impl From<&[T]> for AllocRingBuffer { fn from(value: &[T]) -> Self { - let mut rb = Self::with_capacity_non_power_of_two(value.len()); + let mut rb = Self::new(value.len()); rb.extend(value.iter().cloned()); rb } } -impl From> for AllocRingBuffer { - fn from(mut v: GrowableAllocRingBuffer) -> AllocRingBuffer { - let mut rb = AllocRingBuffer::with_capacity_non_power_of_two(v.len()); +impl From> for AllocRingBuffer { + fn from(mut v: GrowableAllocRingBuffer) -> AllocRingBuffer { + let mut rb = AllocRingBuffer::new(v.len()); rb.extend(v.drain()); rb } } -impl From<&mut [T]> for AllocRingBuffer { +impl From<&mut [T]> for AllocRingBuffer { fn from(value: &mut [T]) -> Self { Self::from(&*value) } } -impl From<&mut [T; CAP]> for AllocRingBuffer { +impl From<&mut [T; CAP]> for AllocRingBuffer { fn from(value: &mut [T; CAP]) -> Self { Self::from(value.clone()) } } -impl From> for AllocRingBuffer { +impl From> for AllocRingBuffer { fn from(value: alloc::vec::Vec) -> Self { - let mut res = AllocRingBuffer::with_capacity_non_power_of_two(value.len()); + let mut res = AllocRingBuffer::new(value.len()); res.extend(value.into_iter()); res } } -impl From> for AllocRingBuffer { +impl From> for AllocRingBuffer { fn from(value: alloc::collections::VecDeque) -> Self { - let mut res = AllocRingBuffer::with_capacity_non_power_of_two(value.len()); + let mut res = AllocRingBuffer::new(value.len()); res.extend(value.into_iter()); res } } -impl From> for AllocRingBuffer { +impl From> for AllocRingBuffer { fn from(value: alloc::collections::LinkedList) -> Self { - let mut res = AllocRingBuffer::with_capacity_non_power_of_two(value.len()); + let mut res = AllocRingBuffer::new(value.len()); res.extend(value.into_iter()); res } } -impl From for AllocRingBuffer { +impl From for AllocRingBuffer { fn from(value: alloc::string::String) -> Self { - let mut res = AllocRingBuffer::with_capacity_non_power_of_two(value.len()); + let mut res = AllocRingBuffer::new(value.len()); res.extend(value.chars()); res } } -impl From<&str> for AllocRingBuffer { +impl From<&str> for AllocRingBuffer { fn from(value: &str) -> Self { - let mut res = AllocRingBuffer::with_capacity_non_power_of_two(value.len()); + let mut res = AllocRingBuffer::new(value.len()); res.extend(value.chars()); res } } -impl From> - for AllocRingBuffer -{ +impl From> for AllocRingBuffer { fn from(mut value: crate::ConstGenericRingBuffer) -> Self { - let mut res = AllocRingBuffer::with_capacity_non_power_of_two(value.len()); + let mut res = AllocRingBuffer::new(value.len()); res.extend(value.drain()); res } } -impl Drop for AllocRingBuffer { +impl Drop for AllocRingBuffer { fn drop(&mut self) { self.drain().for_each(drop); @@ -201,20 +148,17 @@ impl Drop for AllocRingBuffer { } } -impl Clone for AllocRingBuffer { +impl Clone for AllocRingBuffer { fn clone(&self) -> Self { debug_assert_ne!(self.capacity, 0); - debug_assert!(!SIZE::must_be_power_of_two() || self.capacity.is_power_of_two()); - // whatever the previous capacity was, we can just use the same one again. - // It should be valid. - let mut new = unsafe { Self::with_capacity_unchecked(self.capacity) }; + let mut new = Self::new(self.capacity); self.iter().cloned().for_each(|i| new.push(i)); new } } -impl PartialEq for AllocRingBuffer { +impl PartialEq for AllocRingBuffer { fn eq(&self, other: &Self) -> bool { self.capacity == other.capacity && self.len() == other.len() @@ -222,9 +166,9 @@ impl PartialEq for AllocRingBuffer } } -impl Eq for AllocRingBuffer {} +impl Eq for AllocRingBuffer {} -impl IntoIterator for AllocRingBuffer { +impl IntoIterator for AllocRingBuffer { type Item = T; type IntoIter = RingBufferIntoIterator; @@ -233,25 +177,25 @@ impl IntoIterator for AllocRingBuffer { } } -impl<'a, T, SIZE: RingbufferSize> IntoIterator for &'a AllocRingBuffer { +impl<'a, T> IntoIterator for &'a AllocRingBuffer { type Item = &'a T; - type IntoIter = RingBufferIterator<'a, T, AllocRingBuffer>; + type IntoIter = RingBufferIterator<'a, T, AllocRingBuffer>; fn into_iter(self) -> Self::IntoIter { self.iter() } } -impl<'a, T, SIZE: RingbufferSize> IntoIterator for &'a mut AllocRingBuffer { +impl<'a, T> IntoIterator for &'a mut AllocRingBuffer { type Item = &'a mut T; - type IntoIter = RingBufferMutIterator<'a, T, AllocRingBuffer>; + type IntoIter = RingBufferMutIterator<'a, T, AllocRingBuffer>; fn into_iter(self) -> Self::IntoIter { self.iter_mut() } } -impl Extend for AllocRingBuffer { +impl Extend for AllocRingBuffer { fn extend>(&mut self, iter: A) { let iter = iter.into_iter(); @@ -261,7 +205,7 @@ impl Extend for AllocRingBuffer { } } -unsafe impl RingBuffer for AllocRingBuffer { +unsafe impl RingBuffer for AllocRingBuffer { #[inline] unsafe fn ptr_capacity(rb: *const Self) -> usize { (*rb).capacity @@ -272,12 +216,8 @@ unsafe impl RingBuffer for AllocRingBuffer #[inline] fn push(&mut self, value: T) { if self.is_full() { - let previous_value = unsafe { - ptr::read(get_unchecked_mut( - self, - SIZE::mask(self.capacity, self.readptr), - )) - }; + let previous_value = + unsafe { ptr::read(get_unchecked_mut(self, mask(self.size, self.readptr))) }; // make sure we drop whatever is being overwritten // SAFETY: the buffer is full, so this must be initialized @@ -290,7 +230,7 @@ unsafe impl RingBuffer for AllocRingBuffer self.readptr += 1; } - let index = SIZE::mask(self.capacity, self.writeptr); + let index = mask(self.size, self.writeptr); unsafe { ptr::write(get_unchecked_mut(self, index), value); @@ -303,7 +243,7 @@ unsafe impl RingBuffer for AllocRingBuffer if self.is_empty() { None } else { - let index = SIZE::mask(self.capacity, self.readptr); + let index = mask(self.size, self.readptr); let res = unsafe { get_unchecked_mut(self, index) }; self.readptr += 1; @@ -314,13 +254,7 @@ unsafe impl RingBuffer for AllocRingBuffer } } - impl_ringbuffer_ext!( - get_unchecked, - get_unchecked_mut, - readptr, - writeptr, - SIZE::mask - ); + impl_ringbuffer_ext!(get_unchecked, get_unchecked_mut, readptr, writeptr, mask); #[inline] fn fill_with T>(&mut self, mut f: F) { @@ -335,59 +269,13 @@ unsafe impl RingBuffer for AllocRingBuffer } } -impl AllocRingBuffer { - /// Creates a `AllocRingBuffer` with a certain capacity. This capacity is fixed. - /// for this ringbuffer to work, cap must be a power of two and greater than zero. - /// - /// # Safety - /// Only safe if the capacity is greater than zero, and a power of two. - /// Only if `MODE` == [`NonPowerOfTwo`](NonPowerOfTwo) can the capacity be not a power of two, in which case this function is also safe. - #[inline] - unsafe fn with_capacity_unchecked(cap: usize) -> Self { - let layout = alloc::alloc::Layout::array::(cap).unwrap(); - let buf = unsafe { alloc::alloc::alloc(layout) as *mut T }; - - Self { - buf, - capacity: cap, - readptr: 0, - writeptr: 0, - mode: PhantomData, - } - } -} - -impl AllocRingBuffer { - /// Creates a `AllocRingBuffer` with a certain capacity. This capacity is fixed. - /// for this ringbuffer to work, and must not be zero. - /// - /// Note, that not using a power of two means some operations can't be optimized as well. - /// For example, bitwise ands might become modulos. - /// - /// For example, on push operations, benchmarks have shown that a ringbuffer with a power-of-two - /// capacity constructed with `with_capacity_non_power_of_two` (so which don't get the same optimization - /// as the ones constructed with `with_capacity`) can be up to 3x slower - /// - /// # Panics - /// if the capacity is zero - #[inline] - #[must_use] - pub fn with_capacity_non_power_of_two(cap: usize) -> Self { - assert_ne!(cap, 0, "Capacity must be greater than 0"); - - // Safety: Mode is NonPowerOfTwo and we checked above that the capacity isn't zero - unsafe { Self::with_capacity_unchecked(cap) } - } -} - -impl AllocRingBuffer { +impl AllocRingBuffer { /// Creates a `AllocRingBuffer` with a certain capacity. The actual capacity is the input to the /// function raised to the power of two (effectively the input is the log2 of the actual capacity) #[inline] #[must_use] pub fn with_capacity_power_of_2(cap_power_of_two: usize) -> Self { - // Safety: 1 << n is always a power of two, and nonzero - unsafe { Self::with_capacity_unchecked(1 << cap_power_of_two) } + Self::new(1 << cap_power_of_two) } #[inline] @@ -403,22 +291,25 @@ impl AllocRingBuffer { /// Panics when capacity is zero or not a power of two #[inline] #[must_use] - pub fn new(cap: usize) -> Self { - assert_ne!(cap, 0, "Capacity must be greater than 0"); - assert!(cap.is_power_of_two(), "Capacity must be a power of two"); - - // Safety: assertions check that cap is a power of two and nonzero - unsafe { Self::with_capacity_unchecked(cap) } + pub fn new(capacity: usize) -> Self { + assert_ne!(capacity, 0, "Capacity must be greater than 0"); + let size = capacity.next_power_of_two(); + let layout = alloc::alloc::Layout::array::(size).unwrap(); + let buf = unsafe { alloc::alloc::alloc(layout) as *mut T }; + Self { + buf, + size, + capacity, + readptr: 0, + writeptr: 0, + } } } /// Get a reference from the buffer without checking it is initialized. /// Caller must be sure the index is in bounds, or this will panic. #[inline] -unsafe fn get_unchecked<'a, T, SIZE: RingbufferSize>( - rb: *const AllocRingBuffer, - index: usize, -) -> &'a T { +unsafe fn get_unchecked<'a, T>(rb: *const AllocRingBuffer, index: usize) -> &'a T { let p = (*rb).buf.add(index); // Safety: caller makes sure the index is in bounds for the ringbuffer. // All in bounds values in the ringbuffer are initialized @@ -428,10 +319,7 @@ unsafe fn get_unchecked<'a, T, SIZE: RingbufferSize>( /// Get a mut reference from the buffer without checking it is initialized. /// Caller must be sure the index is in bounds, or this will panic. #[inline] -unsafe fn get_unchecked_mut( - rb: *mut AllocRingBuffer, - index: usize, -) -> *mut T { +unsafe fn get_unchecked_mut(rb: *mut AllocRingBuffer, index: usize) -> *mut T { let p = (*rb).buf.add(index); // Safety: caller makes sure the index is in bounds for the ringbuffer. @@ -439,7 +327,7 @@ unsafe fn get_unchecked_mut( p.cast() } -impl Index for AllocRingBuffer { +impl Index for AllocRingBuffer { type Output = T; fn index(&self, index: isize) -> &Self::Output { @@ -447,7 +335,7 @@ impl Index for AllocRingBuffer { } } -impl IndexMut for AllocRingBuffer { +impl IndexMut for AllocRingBuffer { fn index_mut(&mut self, index: isize) -> &mut Self::Output { self.get_mut(index).expect("index out of bounds") } @@ -455,25 +343,22 @@ impl IndexMut for AllocRingBuffer { #[cfg(test)] mod tests { - use crate::with_alloc::alloc_ringbuffer::RingbufferSize; use crate::{AllocRingBuffer, RingBuffer}; // just test that this compiles #[test] fn test_generic_clone() { - fn helper( - a: &AllocRingBuffer, - ) -> AllocRingBuffer { + fn helper(a: &AllocRingBuffer) -> AllocRingBuffer { a.clone() } _ = helper(&AllocRingBuffer::new(2)); - _ = helper(&AllocRingBuffer::with_capacity_non_power_of_two(5)); + _ = helper(&AllocRingBuffer::new(5)); } #[test] fn test_not_power_of_two() { - let mut rb = AllocRingBuffer::with_capacity_non_power_of_two(10); + let mut rb = AllocRingBuffer::new(10); const NUM_VALS: usize = 1000; // recycle the ringbuffer a bunch of time to see if noneof the logic @@ -498,12 +383,6 @@ mod tests { assert_eq!(b.capacity, 4); } - #[test] - #[should_panic] - fn test_with_capacity_no_power_of_two() { - let _ = AllocRingBuffer::::new(10); - } - #[test] #[should_panic] fn test_index_zero_length() { diff --git a/src/with_alloc/vecdeque.rs b/src/with_alloc/vecdeque.rs index 73e63d4..9eeaa4e 100644 --- a/src/with_alloc/vecdeque.rs +++ b/src/with_alloc/vecdeque.rs @@ -1,5 +1,4 @@ use crate::ringbuffer_trait::{RingBufferIntoIterator, RingBufferIterator, RingBufferMutIterator}; -use crate::with_alloc::alloc_ringbuffer::RingbufferSize; use crate::{AllocRingBuffer, RingBuffer}; use alloc::collections::VecDeque; use core::ops::{Deref, DerefMut, Index, IndexMut}; @@ -40,8 +39,8 @@ impl From<&[T]> for GrowableAllocRingBuffer { } } -impl From> for GrowableAllocRingBuffer { - fn from(mut v: AllocRingBuffer) -> GrowableAllocRingBuffer { +impl From> for GrowableAllocRingBuffer { + fn from(mut v: AllocRingBuffer) -> GrowableAllocRingBuffer { let mut rb = GrowableAllocRingBuffer::new(); rb.extend(v.drain()); rb diff --git a/src/with_const_generics.rs b/src/with_const_generics.rs index 87a9baa..b2aadea 100644 --- a/src/with_const_generics.rs +++ b/src/with_const_generics.rs @@ -1,5 +1,4 @@ use crate::ringbuffer_trait::{RingBufferIntoIterator, RingBufferIterator, RingBufferMutIterator}; -use crate::with_alloc::alloc_ringbuffer::RingbufferSize; use crate::RingBuffer; use core::iter::FromIterator; use core::mem; @@ -124,10 +123,8 @@ impl From> } #[cfg(feature = "alloc")] -impl From> - for ConstGenericRingBuffer -{ - fn from(mut value: crate::AllocRingBuffer) -> Self { +impl From> for ConstGenericRingBuffer { + fn from(mut value: crate::AllocRingBuffer) -> Self { value.drain().collect() } } diff --git a/tests/conversions.rs b/tests/conversions.rs index 5816a5e..481b4ca 100644 --- a/tests/conversions.rs +++ b/tests/conversions.rs @@ -45,7 +45,7 @@ convert_tests!( alloc_from_cgrb: {let a = ConstGenericRingBuffer::from(['1', '2']); a}, alloc_from_garb: {let a = GrowableAllocRingBuffer::from(['1', '2']); a}, - ] => AllocRingBuffer::<_, _> + ] => AllocRingBuffer::<_> ); convert_tests!( From d79e3bbd7b2b0934e687c6675111ecc4d9bb451d Mon Sep 17 00:00:00 2001 From: jdonszelmann Date: Fri, 15 Sep 2023 11:29:14 +0200 Subject: [PATCH 2/5] fix ci --- benchmarks.txt | 314 +++++++++++++++++++++++++++++++++++++ src/with_const_generics.rs | 3 - 2 files changed, 314 insertions(+), 3 deletions(-) create mode 100644 benchmarks.txt diff --git a/benchmarks.txt b/benchmarks.txt new file mode 100644 index 0000000..d196ae5 --- /dev/null +++ b/benchmarks.txt @@ -0,0 +1,314 @@ +single-ops/push empty: [alloc] non-power-of-two + time: [2.2171 ns 2.2190 ns 2.2209 ns] + change: [-2.1304% +0.0959% +2.5258%] (p = 0.94 > 0.05) + No change in performance detected. +Found 5068 outliers among 40000 measurements (12.67%) + 1 (0.00%) low mild + 2149 (5.37%) high mild + 2918 (7.29%) high severe +single-ops/push empty: [const-generic] non-power-of-two + time: [1.4038 ns 1.4055 ns 1.4071 ns] + change: [-0.3491% +1.4592% +3.3064%] (p = 0.13 > 0.05) + No change in performance detected. +Found 5435 outliers among 40000 measurements (13.59%) + 2465 (6.16%) high mild + 2970 (7.42%) high severe +single-ops/push empty: [growable] non-power-of-two + time: [1.7230 ns 1.7247 ns 1.7264 ns] + change: [-3.8615% -0.7609% +2.2804%] (p = 0.66 > 0.05) + No change in performance detected. +Found 5144 outliers among 40000 measurements (12.86%) + 2319 (5.80%) high mild + 2825 (7.06%) high severe +single-ops/push empty: [alloc] power-of-two + time: [1.9350 ns 1.9371 ns 1.9391 ns] + change: [-3.6773% -1.1380% +1.2111%] (p = 0.42 > 0.05) + No change in performance detected. +Found 5095 outliers among 40000 measurements (12.74%) + 2350 (5.88%) high mild + 2745 (6.86%) high severe +single-ops/push empty: [const-generic] power-of-two + time: [1.5533 ns 1.5566 ns 1.5598 ns] + change: [-4.8134% -2.9662% -1.2320%] (p = 0.00 < 0.05) + Performance has improved. +Found 2308 outliers among 40000 measurements (5.77%) + 1517 (3.79%) high mild + 791 (1.98%) high severe +single-ops/push empty: [growable] power-of-two + time: [1.9730 ns 1.9753 ns 1.9776 ns] + change: [-1.6385% +1.2771% +4.1091%] (p = 0.41 > 0.05) + No change in performance detected. +Found 5231 outliers among 40000 measurements (13.08%) + 2217 (5.54%) high mild + 3014 (7.54%) high severe +Benchmarking single-ops/push full: [alloc] non-power-of-two: Warming up for 5.0000 s +Warning: Unable to complete 40000 samples in 60.0s. You may wish to increase target time to 62.2s, enable flat sampling, or reduce sample count to 27780. +single-ops/push full: [alloc] non-power-of-two + time: [2.2195 ns 2.2222 ns 2.2250 ns] + change: [-3.6735% -0.0019% +3.5666%] (p = 0.99 > 0.05) + No change in performance detected. +Found 5154 outliers among 40000 measurements (12.88%) + 1 (0.00%) low mild + 2060 (5.15%) high mild + 3093 (7.73%) high severe +single-ops/push full: [const-generic] non-power-of-two + time: [1.8389 ns 1.8417 ns 1.8444 ns] + change: [-7.5073% -5.9821% -4.2554%] (p = 0.00 < 0.05) + Performance has improved. +Found 4448 outliers among 40000 measurements (11.12%) + 2064 (5.16%) high mild + 2384 (5.96%) high severe +Benchmarking single-ops/push full: [growable] non-power-of-two: Warming up for 5.0000 s +Warning: Unable to complete 40000 samples in 60.0s. You may wish to increase target time to 110.9s, enable flat sampling, or reduce sample count to 20800. +single-ops/push full: [growable] non-power-of-two + time: [45.465 ns 45.486 ns 45.508 ns] + change: [-1.0386% -0.7004% -0.3403%] (p = 0.00 < 0.05) + Change within noise threshold. +Found 7744 outliers among 40000 measurements (19.36%) + 4737 (11.84%) low severe + 1945 (4.86%) low mild + 859 (2.15%) high mild + 203 (0.51%) high severe +Benchmarking single-ops/push full: [alloc] power-of-two: Warming up for 5.0000 s +Warning: Unable to complete 40000 samples in 60.0s. You may wish to increase target time to 70.9s, enable flat sampling, or reduce sample count to 26020. +single-ops/push full: [alloc] power-of-two + time: [2.4978 ns 2.5010 ns 2.5043 ns] + change: [-5.5180% -1.5653% +2.6720%] (p = 0.45 > 0.05) + No change in performance detected. +Found 4662 outliers among 40000 measurements (11.65%) + 26 (0.07%) low severe + 488 (1.22%) low mild + 883 (2.21%) high mild + 3265 (8.16%) high severe +single-ops/push full: [const-generic] power-of-two + time: [2.1352 ns 2.1402 ns 2.1458 ns] + change: [-21.074% -19.522% -17.381%] (p = 0.00 < 0.05) + Performance has improved. +Found 4147 outliers among 40000 measurements (10.37%) + 3 (0.01%) low severe + 13 (0.03%) low mild + 1855 (4.64%) high mild + 2276 (5.69%) high severe +Benchmarking single-ops/push full: [growable] power-of-two: Warming up for 5.0000 s +Warning: Unable to complete 40000 samples in 60.0s. You may wish to increase target time to 158.9s, enable flat sampling, or reduce sample count to 17380. +single-ops/push full: [growable] power-of-two + time: [45.138 ns 45.150 ns 45.162 ns] + change: [+1.6296% +1.9816% +2.3989%] (p = 0.00 < 0.05) + Performance has regressed. +Found 7365 outliers among 40000 measurements (18.41%) + 6387 (15.97%) high mild + 978 (2.44%) high severe +single-ops/dequeue with item: [alloc] non-power-of-two + time: [1.9709 ns 1.9728 ns 1.9747 ns] + change: [-2.9691% -0.9493% +1.2088%] (p = 0.38 > 0.05) + No change in performance detected. +Found 5038 outliers among 40000 measurements (12.60%) + 2169 (5.42%) high mild + 2869 (7.17%) high severe +single-ops/dequeue with item: [const-generic] non-power-of-two + time: [1.6940 ns 1.6966 ns 1.6992 ns] + change: [-1.0007% -0.0600% +0.9255%] (p = 0.90 > 0.05) + No change in performance detected. +Found 3384 outliers among 40000 measurements (8.46%) + 1815 (4.54%) high mild + 1569 (3.92%) high severe +single-ops/dequeue with item: [growable] non-power-of-two + time: [1.7228 ns 1.7282 ns 1.7372 ns] + change: [-3.1990% +0.0436% +3.3303%] (p = 0.99 > 0.05) + No change in performance detected. +Found 5127 outliers among 40000 measurements (12.82%) + 2384 (5.96%) high mild + 2743 (6.86%) high severe +single-ops/dequeue with item: [alloc] power-of-two + time: [1.7149 ns 1.7175 ns 1.7202 ns] + change: [-3.7510% -0.4551% +2.5486%] (p = 0.81 > 0.05) + No change in performance detected. +Found 4400 outliers among 40000 measurements (11.00%) + 2109 (5.27%) high mild + 2291 (5.73%) high severe +single-ops/dequeue with item: [const-generic] power-of-two + time: [1.5067 ns 1.5094 ns 1.5120 ns] + change: [-22.281% -15.774% -10.977%] (p = 0.00 < 0.05) + Performance has improved. +Found 3546 outliers among 40000 measurements (8.87%) + 1822 (4.55%) high mild + 1724 (4.31%) high severe +single-ops/dequeue with item: [growable] power-of-two + time: [1.8362 ns 1.8390 ns 1.8418 ns] + change: [-2.9027% +0.2452% +3.0412%] (p = 0.89 > 0.05) + No change in performance detected. +Found 4389 outliers among 40000 measurements (10.97%) + 2151 (5.38%) high mild + 2238 (5.59%) high severe +single-ops/dequeue empty: [alloc] non-power-of-two + time: [818.30 ps 819.69 ps 821.13 ps] + change: [-3.5637% +0.7797% +5.9616%] (p = 0.74 > 0.05) + No change in performance detected. +Found 5517 outliers among 40000 measurements (13.79%) + 2201 (5.50%) high mild + 3316 (8.29%) high severe +single-ops/dequeue empty: [const-generic] non-power-of-two + time: [947.50 ps 949.45 ps 951.45 ps] + change: [-1.9480% +0.4418% +3.2377%] (p = 0.76 > 0.05) + No change in performance detected. +Found 3704 outliers among 40000 measurements (9.26%) + 1 (0.00%) low mild + 1778 (4.45%) high mild + 1925 (4.81%) high severe +single-ops/dequeue empty: [growable] non-power-of-two + time: [756.13 ps 757.70 ps 759.30 ps] + change: [-4.3287% +0.3643% +5.0731%] (p = 0.90 > 0.05) + No change in performance detected. +Found 5731 outliers among 40000 measurements (14.33%) + 2134 (5.33%) high mild + 3597 (8.99%) high severe +single-ops/dequeue empty: [alloc] power-of-two + time: [825.04 ps 826.37 ps 827.74 ps] + change: [-7.2408% -1.8290% +3.3766%] (p = 0.52 > 0.05) + No change in performance detected. +Found 5520 outliers among 40000 measurements (13.80%) + 1919 (4.80%) high mild + 3601 (9.00%) high severe +single-ops/dequeue empty: [const-generic] power-of-two + time: [1.4789 ns 1.4841 ns 1.4893 ns] + change: [-2.2150% +0.2400% +2.5669%] (p = 0.86 > 0.05) + No change in performance detected. +Found 2207 outliers among 40000 measurements (5.52%) + 1706 (4.26%) high mild + 501 (1.25%) high sever1.48ns e +single-ops/dequeue empty: [growable] power-of-two + time: [745.35 ps 746.82 ps 748.32 ps] + change: [-5.3157% +0.2962% +7.5298%] (p = 0.94 > 0.05) + No change in performance detected. +Found 5479 outliers among 40000 measurements (13.70%) + 1794 (4.49%) high mild + 3685 (9.21%) high severe + +batch/fill: [alloc] non-power-of-two + time: [1.9029 µs 1.9037 µs 1.9045 µs] + change: [-1.2312% -0.4263% +0.4084%] (p = 0.32 > 0.05) + No change in performance detected. +Found 147 outliers among 1000 measurements (14.70%) + 43 (4.30%) high mild + 104 (10.40%) high severe +batch/fill: [const-generic] non-power-of-two + time: [1.2678 µs 1.2684 µs 1.2690 µs] + change: [-2.3283% -1.0501% +0.2622%] (p = 0.09 > 0.05) + No change in performance detected. +Found 129 outliers among 1000 measurements (12.90%) + 50 (5.00%) high mild + 79 (7.90%) high severe +batch/fill: [growable] non-power-of-two + time: [1.1570 µs 1.1585 µs 1.1601 µs] + change: [-1.5585% -0.6117% +0.4033%] (p = 0.24 > 0.05) + No change in performance detected. +Found 122 outliers among 1000 measurements (12.20%) + 25 (2.50%) high mild + 97 (9.70%) high severe +batch/fill: [alloc] power-of-two + time: [1.1047 µs 1.1053 µs 1.1059 µs] + change: [-1.8509% -0.4286% +1.1297%] (p = 0.57 > 0.05) + No change in performance detected. +Found 119 outliers among 1000 measurements (11.90%) + 17 (1.70%) high mild + 102 (10.20%) high severe +batch/fill: [const-generic] power-of-two + time: [1.0121 µs 1.0127 µs 1.0133 µs] + change: [-1.2907% -0.2821% +0.7342%] (p = 0.62 > 0.05) + No change in performance detected. +Found 111 outliers among 1000 measurements (11.10%) + 52 (5.20%) high mild + 59 (5.90%) high severe +batch/fill: [growable] power-of-two + time: [1.1807 µs 1.1824 µs 1.1840 µs] + change: [-0.7709% +0.1560% +1.0762%] (p = 0.76 > 0.05) + No change in performance detected. +Found 118 outliers among 1000 measurements (11.80%) + 19 (1.90%) high mild + 99 (9.90%) high severe +batch/over fill: [alloc] non-power-of-two + time: [3.8041 µs 3.8102 µs 3.8165 µs] + change: [-0.6518% -0.0744% +0.4735%] (p = 0.80 > 0.05) + No change in performance detected. +Found 73 outliers among 1000 measurements (7.30%) + 38 (3.80%) high mild + 35 (3.50%) high severe +batch/over fill: [const-generic] non-power-of-two + time: [2.5193 µs 2.5255 µs 2.5338 µs] + change: [-0.2462% +0.3881% +0.9729%] (p = 0.24 > 0.05) + No change in performance detected. +Found 105 outliers among 1000 measurements (10.50%) + 50 (5.00%) high mild + 55 (5.50%) high severe +batch/over fill: [growable] non-power-of-two + time: [2.5351 µs 2.5415 µs 2.5486 µs] + change: [-0.4974% +0.0559% +0.6021%] (p = 0.84 > 0.05) + No change in performance detected. +Found 115 outliers among 1000 measurements (11.50%) + 25 (2.50%) high mild + 90 (9.00%) high severe +batch/over fill: [alloc] power-of-two + time: [2.4303 µs 2.4316 µs 2.4330 µs] + change: [-0.9993% -0.1030% +0.7939%] (p = 0.82 > 0.05) + No change in performance detected. +Found 157 outliers among 1000 measurements (15.70%) + 78 (7.80%) high mild + 79 (7.90%) high severe +batch/over fill: [const-generic] power-of-two + time: [2.2951 µs 2.2964 µs 2.2978 µs] + change: [+0.0424% +0.5226% +1.0120%] (p = 0.04 < 0.05) + Change within noise threshold. +Found 94 outliers among 1000 measurements (9.40%) + 47 (4.70%) high mild + 47 (4.70%) high severe +batch/over fill: [growable] power-of-two + time: [2.5752 µs 2.5788 µs 2.5824 µs] + change: [-0.5484% -0.0277% +0.5390%] (p = 0.91 > 0.05) + No change in performance detected. +Found 88 outliers among 1000 measurements (8.80%) + 2 (0.20%) high mild + 86 (8.60%) high severe +batch/drain: [alloc] non-power-of-two + time: [1.8829 µs 1.8839 µs 1.8851 µs] + change: [-0.7758% +0.0096% +0.9608%] (p = 0.98 > 0.05) + No change in performance detected. +Found 128 outliers among 1000 measurements (12.80%) + 52 (5.20%) high mild + 76 (7.60%) high severe +batch/drain: [const-generic] non-power-of-two + time: [919.48 ns 929.11 ns 939.39 ns] + change: [-9.3230% -7.6811% -6.1789%] (p = 0.00 < 0.05) + Performance has improved. +Found 20 outliers among 1000 measurements (2.00%) + 18 (1.80%) high mild + 2 (0.20%) high severe +Benchmarking batch/drain: [growable] non-power-of-two: Collecting 1000 samples in estimated 60.227 s (28M iterations) +batch/drain: [growable] non-power-of-two + time: [1.3952 µs 1.3959 µs 1.3967 µs] + change: [-26.598% -25.889% -25.222%] (p = 0.00 < 0.05) + Performance has improved. +Found 119 outliers among 1000 measurements (11.90%) + 45 (4.50%) high mild + 74 (7.40%) high severe +batch/drain: [alloc] power-of-two + time: [832.98 ns 835.50 ns 838.36 ns] + change: [-25.845% -25.060% -24.298%] (p = 0.00 < 0.05) + Performance has improved. +Found 151 outliers among 1000 measurements (15.10%) + 50 (5.00%) high mild + 101 (10.10%) high severe +batch/drain: [const-generic] power-of-two + time: [605.55 ns 610.90 ns 617.00 ns] + change: [-25.743% -24.437% -22.831%] (p = 0.00 < 0.05) + Performance has improved. +Found 133 outliers among 1000 measurements (13.30%) + 43 (4.30%) high mild + 90 (9.00%) high severe +batch/drain: [growable] power-of-two + time: [1.4447 µs 1.4467 µs 1.4492 µs] + change: [-25.692% -25.022% -24.274%] (p = 0.00 < 0.05) + Performance has improved. +Found 130 outliers among 1000 measurements (13.00%) + 40 (4.00%) high mild + 90 (9.00%) high severe + diff --git a/src/with_const_generics.rs b/src/with_const_generics.rs index 2be6c68..e7eabd9 100644 --- a/src/with_const_generics.rs +++ b/src/with_const_generics.rs @@ -5,9 +5,6 @@ use core::mem; use core::mem::MaybeUninit; use core::ops::{Index, IndexMut}; -#[cfg(feature = "alloc")] -use crate::with_alloc::alloc_ringbuffer::RingbufferSize; - /// The `ConstGenericRingBuffer` struct is a `RingBuffer` implementation which does not require `alloc` but /// uses const generics instead. /// From 169a34a5f86fb64865dd5fd9f3f7347fcff1d447 Mon Sep 17 00:00:00 2001 From: jdonszelmann Date: Fri, 15 Sep 2023 11:31:20 +0200 Subject: [PATCH 3/5] fix docs --- .gitignore | 1 + benchmarks.txt | 314 ----------------------------- src/with_alloc/alloc_ringbuffer.rs | 12 +- 3 files changed, 11 insertions(+), 316 deletions(-) delete mode 100644 benchmarks.txt diff --git a/.gitignore b/.gitignore index 15d4356..6ea059b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /target **/*.rs.bk Cargo.lock +benchmarks.txt # Editors .idea diff --git a/benchmarks.txt b/benchmarks.txt deleted file mode 100644 index d196ae5..0000000 --- a/benchmarks.txt +++ /dev/null @@ -1,314 +0,0 @@ -single-ops/push empty: [alloc] non-power-of-two - time: [2.2171 ns 2.2190 ns 2.2209 ns] - change: [-2.1304% +0.0959% +2.5258%] (p = 0.94 > 0.05) - No change in performance detected. -Found 5068 outliers among 40000 measurements (12.67%) - 1 (0.00%) low mild - 2149 (5.37%) high mild - 2918 (7.29%) high severe -single-ops/push empty: [const-generic] non-power-of-two - time: [1.4038 ns 1.4055 ns 1.4071 ns] - change: [-0.3491% +1.4592% +3.3064%] (p = 0.13 > 0.05) - No change in performance detected. -Found 5435 outliers among 40000 measurements (13.59%) - 2465 (6.16%) high mild - 2970 (7.42%) high severe -single-ops/push empty: [growable] non-power-of-two - time: [1.7230 ns 1.7247 ns 1.7264 ns] - change: [-3.8615% -0.7609% +2.2804%] (p = 0.66 > 0.05) - No change in performance detected. -Found 5144 outliers among 40000 measurements (12.86%) - 2319 (5.80%) high mild - 2825 (7.06%) high severe -single-ops/push empty: [alloc] power-of-two - time: [1.9350 ns 1.9371 ns 1.9391 ns] - change: [-3.6773% -1.1380% +1.2111%] (p = 0.42 > 0.05) - No change in performance detected. -Found 5095 outliers among 40000 measurements (12.74%) - 2350 (5.88%) high mild - 2745 (6.86%) high severe -single-ops/push empty: [const-generic] power-of-two - time: [1.5533 ns 1.5566 ns 1.5598 ns] - change: [-4.8134% -2.9662% -1.2320%] (p = 0.00 < 0.05) - Performance has improved. -Found 2308 outliers among 40000 measurements (5.77%) - 1517 (3.79%) high mild - 791 (1.98%) high severe -single-ops/push empty: [growable] power-of-two - time: [1.9730 ns 1.9753 ns 1.9776 ns] - change: [-1.6385% +1.2771% +4.1091%] (p = 0.41 > 0.05) - No change in performance detected. -Found 5231 outliers among 40000 measurements (13.08%) - 2217 (5.54%) high mild - 3014 (7.54%) high severe -Benchmarking single-ops/push full: [alloc] non-power-of-two: Warming up for 5.0000 s -Warning: Unable to complete 40000 samples in 60.0s. You may wish to increase target time to 62.2s, enable flat sampling, or reduce sample count to 27780. -single-ops/push full: [alloc] non-power-of-two - time: [2.2195 ns 2.2222 ns 2.2250 ns] - change: [-3.6735% -0.0019% +3.5666%] (p = 0.99 > 0.05) - No change in performance detected. -Found 5154 outliers among 40000 measurements (12.88%) - 1 (0.00%) low mild - 2060 (5.15%) high mild - 3093 (7.73%) high severe -single-ops/push full: [const-generic] non-power-of-two - time: [1.8389 ns 1.8417 ns 1.8444 ns] - change: [-7.5073% -5.9821% -4.2554%] (p = 0.00 < 0.05) - Performance has improved. -Found 4448 outliers among 40000 measurements (11.12%) - 2064 (5.16%) high mild - 2384 (5.96%) high severe -Benchmarking single-ops/push full: [growable] non-power-of-two: Warming up for 5.0000 s -Warning: Unable to complete 40000 samples in 60.0s. You may wish to increase target time to 110.9s, enable flat sampling, or reduce sample count to 20800. -single-ops/push full: [growable] non-power-of-two - time: [45.465 ns 45.486 ns 45.508 ns] - change: [-1.0386% -0.7004% -0.3403%] (p = 0.00 < 0.05) - Change within noise threshold. -Found 7744 outliers among 40000 measurements (19.36%) - 4737 (11.84%) low severe - 1945 (4.86%) low mild - 859 (2.15%) high mild - 203 (0.51%) high severe -Benchmarking single-ops/push full: [alloc] power-of-two: Warming up for 5.0000 s -Warning: Unable to complete 40000 samples in 60.0s. You may wish to increase target time to 70.9s, enable flat sampling, or reduce sample count to 26020. -single-ops/push full: [alloc] power-of-two - time: [2.4978 ns 2.5010 ns 2.5043 ns] - change: [-5.5180% -1.5653% +2.6720%] (p = 0.45 > 0.05) - No change in performance detected. -Found 4662 outliers among 40000 measurements (11.65%) - 26 (0.07%) low severe - 488 (1.22%) low mild - 883 (2.21%) high mild - 3265 (8.16%) high severe -single-ops/push full: [const-generic] power-of-two - time: [2.1352 ns 2.1402 ns 2.1458 ns] - change: [-21.074% -19.522% -17.381%] (p = 0.00 < 0.05) - Performance has improved. -Found 4147 outliers among 40000 measurements (10.37%) - 3 (0.01%) low severe - 13 (0.03%) low mild - 1855 (4.64%) high mild - 2276 (5.69%) high severe -Benchmarking single-ops/push full: [growable] power-of-two: Warming up for 5.0000 s -Warning: Unable to complete 40000 samples in 60.0s. You may wish to increase target time to 158.9s, enable flat sampling, or reduce sample count to 17380. -single-ops/push full: [growable] power-of-two - time: [45.138 ns 45.150 ns 45.162 ns] - change: [+1.6296% +1.9816% +2.3989%] (p = 0.00 < 0.05) - Performance has regressed. -Found 7365 outliers among 40000 measurements (18.41%) - 6387 (15.97%) high mild - 978 (2.44%) high severe -single-ops/dequeue with item: [alloc] non-power-of-two - time: [1.9709 ns 1.9728 ns 1.9747 ns] - change: [-2.9691% -0.9493% +1.2088%] (p = 0.38 > 0.05) - No change in performance detected. -Found 5038 outliers among 40000 measurements (12.60%) - 2169 (5.42%) high mild - 2869 (7.17%) high severe -single-ops/dequeue with item: [const-generic] non-power-of-two - time: [1.6940 ns 1.6966 ns 1.6992 ns] - change: [-1.0007% -0.0600% +0.9255%] (p = 0.90 > 0.05) - No change in performance detected. -Found 3384 outliers among 40000 measurements (8.46%) - 1815 (4.54%) high mild - 1569 (3.92%) high severe -single-ops/dequeue with item: [growable] non-power-of-two - time: [1.7228 ns 1.7282 ns 1.7372 ns] - change: [-3.1990% +0.0436% +3.3303%] (p = 0.99 > 0.05) - No change in performance detected. -Found 5127 outliers among 40000 measurements (12.82%) - 2384 (5.96%) high mild - 2743 (6.86%) high severe -single-ops/dequeue with item: [alloc] power-of-two - time: [1.7149 ns 1.7175 ns 1.7202 ns] - change: [-3.7510% -0.4551% +2.5486%] (p = 0.81 > 0.05) - No change in performance detected. -Found 4400 outliers among 40000 measurements (11.00%) - 2109 (5.27%) high mild - 2291 (5.73%) high severe -single-ops/dequeue with item: [const-generic] power-of-two - time: [1.5067 ns 1.5094 ns 1.5120 ns] - change: [-22.281% -15.774% -10.977%] (p = 0.00 < 0.05) - Performance has improved. -Found 3546 outliers among 40000 measurements (8.87%) - 1822 (4.55%) high mild - 1724 (4.31%) high severe -single-ops/dequeue with item: [growable] power-of-two - time: [1.8362 ns 1.8390 ns 1.8418 ns] - change: [-2.9027% +0.2452% +3.0412%] (p = 0.89 > 0.05) - No change in performance detected. -Found 4389 outliers among 40000 measurements (10.97%) - 2151 (5.38%) high mild - 2238 (5.59%) high severe -single-ops/dequeue empty: [alloc] non-power-of-two - time: [818.30 ps 819.69 ps 821.13 ps] - change: [-3.5637% +0.7797% +5.9616%] (p = 0.74 > 0.05) - No change in performance detected. -Found 5517 outliers among 40000 measurements (13.79%) - 2201 (5.50%) high mild - 3316 (8.29%) high severe -single-ops/dequeue empty: [const-generic] non-power-of-two - time: [947.50 ps 949.45 ps 951.45 ps] - change: [-1.9480% +0.4418% +3.2377%] (p = 0.76 > 0.05) - No change in performance detected. -Found 3704 outliers among 40000 measurements (9.26%) - 1 (0.00%) low mild - 1778 (4.45%) high mild - 1925 (4.81%) high severe -single-ops/dequeue empty: [growable] non-power-of-two - time: [756.13 ps 757.70 ps 759.30 ps] - change: [-4.3287% +0.3643% +5.0731%] (p = 0.90 > 0.05) - No change in performance detected. -Found 5731 outliers among 40000 measurements (14.33%) - 2134 (5.33%) high mild - 3597 (8.99%) high severe -single-ops/dequeue empty: [alloc] power-of-two - time: [825.04 ps 826.37 ps 827.74 ps] - change: [-7.2408% -1.8290% +3.3766%] (p = 0.52 > 0.05) - No change in performance detected. -Found 5520 outliers among 40000 measurements (13.80%) - 1919 (4.80%) high mild - 3601 (9.00%) high severe -single-ops/dequeue empty: [const-generic] power-of-two - time: [1.4789 ns 1.4841 ns 1.4893 ns] - change: [-2.2150% +0.2400% +2.5669%] (p = 0.86 > 0.05) - No change in performance detected. -Found 2207 outliers among 40000 measurements (5.52%) - 1706 (4.26%) high mild - 501 (1.25%) high sever1.48ns e -single-ops/dequeue empty: [growable] power-of-two - time: [745.35 ps 746.82 ps 748.32 ps] - change: [-5.3157% +0.2962% +7.5298%] (p = 0.94 > 0.05) - No change in performance detected. -Found 5479 outliers among 40000 measurements (13.70%) - 1794 (4.49%) high mild - 3685 (9.21%) high severe - -batch/fill: [alloc] non-power-of-two - time: [1.9029 µs 1.9037 µs 1.9045 µs] - change: [-1.2312% -0.4263% +0.4084%] (p = 0.32 > 0.05) - No change in performance detected. -Found 147 outliers among 1000 measurements (14.70%) - 43 (4.30%) high mild - 104 (10.40%) high severe -batch/fill: [const-generic] non-power-of-two - time: [1.2678 µs 1.2684 µs 1.2690 µs] - change: [-2.3283% -1.0501% +0.2622%] (p = 0.09 > 0.05) - No change in performance detected. -Found 129 outliers among 1000 measurements (12.90%) - 50 (5.00%) high mild - 79 (7.90%) high severe -batch/fill: [growable] non-power-of-two - time: [1.1570 µs 1.1585 µs 1.1601 µs] - change: [-1.5585% -0.6117% +0.4033%] (p = 0.24 > 0.05) - No change in performance detected. -Found 122 outliers among 1000 measurements (12.20%) - 25 (2.50%) high mild - 97 (9.70%) high severe -batch/fill: [alloc] power-of-two - time: [1.1047 µs 1.1053 µs 1.1059 µs] - change: [-1.8509% -0.4286% +1.1297%] (p = 0.57 > 0.05) - No change in performance detected. -Found 119 outliers among 1000 measurements (11.90%) - 17 (1.70%) high mild - 102 (10.20%) high severe -batch/fill: [const-generic] power-of-two - time: [1.0121 µs 1.0127 µs 1.0133 µs] - change: [-1.2907% -0.2821% +0.7342%] (p = 0.62 > 0.05) - No change in performance detected. -Found 111 outliers among 1000 measurements (11.10%) - 52 (5.20%) high mild - 59 (5.90%) high severe -batch/fill: [growable] power-of-two - time: [1.1807 µs 1.1824 µs 1.1840 µs] - change: [-0.7709% +0.1560% +1.0762%] (p = 0.76 > 0.05) - No change in performance detected. -Found 118 outliers among 1000 measurements (11.80%) - 19 (1.90%) high mild - 99 (9.90%) high severe -batch/over fill: [alloc] non-power-of-two - time: [3.8041 µs 3.8102 µs 3.8165 µs] - change: [-0.6518% -0.0744% +0.4735%] (p = 0.80 > 0.05) - No change in performance detected. -Found 73 outliers among 1000 measurements (7.30%) - 38 (3.80%) high mild - 35 (3.50%) high severe -batch/over fill: [const-generic] non-power-of-two - time: [2.5193 µs 2.5255 µs 2.5338 µs] - change: [-0.2462% +0.3881% +0.9729%] (p = 0.24 > 0.05) - No change in performance detected. -Found 105 outliers among 1000 measurements (10.50%) - 50 (5.00%) high mild - 55 (5.50%) high severe -batch/over fill: [growable] non-power-of-two - time: [2.5351 µs 2.5415 µs 2.5486 µs] - change: [-0.4974% +0.0559% +0.6021%] (p = 0.84 > 0.05) - No change in performance detected. -Found 115 outliers among 1000 measurements (11.50%) - 25 (2.50%) high mild - 90 (9.00%) high severe -batch/over fill: [alloc] power-of-two - time: [2.4303 µs 2.4316 µs 2.4330 µs] - change: [-0.9993% -0.1030% +0.7939%] (p = 0.82 > 0.05) - No change in performance detected. -Found 157 outliers among 1000 measurements (15.70%) - 78 (7.80%) high mild - 79 (7.90%) high severe -batch/over fill: [const-generic] power-of-two - time: [2.2951 µs 2.2964 µs 2.2978 µs] - change: [+0.0424% +0.5226% +1.0120%] (p = 0.04 < 0.05) - Change within noise threshold. -Found 94 outliers among 1000 measurements (9.40%) - 47 (4.70%) high mild - 47 (4.70%) high severe -batch/over fill: [growable] power-of-two - time: [2.5752 µs 2.5788 µs 2.5824 µs] - change: [-0.5484% -0.0277% +0.5390%] (p = 0.91 > 0.05) - No change in performance detected. -Found 88 outliers among 1000 measurements (8.80%) - 2 (0.20%) high mild - 86 (8.60%) high severe -batch/drain: [alloc] non-power-of-two - time: [1.8829 µs 1.8839 µs 1.8851 µs] - change: [-0.7758% +0.0096% +0.9608%] (p = 0.98 > 0.05) - No change in performance detected. -Found 128 outliers among 1000 measurements (12.80%) - 52 (5.20%) high mild - 76 (7.60%) high severe -batch/drain: [const-generic] non-power-of-two - time: [919.48 ns 929.11 ns 939.39 ns] - change: [-9.3230% -7.6811% -6.1789%] (p = 0.00 < 0.05) - Performance has improved. -Found 20 outliers among 1000 measurements (2.00%) - 18 (1.80%) high mild - 2 (0.20%) high severe -Benchmarking batch/drain: [growable] non-power-of-two: Collecting 1000 samples in estimated 60.227 s (28M iterations) -batch/drain: [growable] non-power-of-two - time: [1.3952 µs 1.3959 µs 1.3967 µs] - change: [-26.598% -25.889% -25.222%] (p = 0.00 < 0.05) - Performance has improved. -Found 119 outliers among 1000 measurements (11.90%) - 45 (4.50%) high mild - 74 (7.40%) high severe -batch/drain: [alloc] power-of-two - time: [832.98 ns 835.50 ns 838.36 ns] - change: [-25.845% -25.060% -24.298%] (p = 0.00 < 0.05) - Performance has improved. -Found 151 outliers among 1000 measurements (15.10%) - 50 (5.00%) high mild - 101 (10.10%) high severe -batch/drain: [const-generic] power-of-two - time: [605.55 ns 610.90 ns 617.00 ns] - change: [-25.743% -24.437% -22.831%] (p = 0.00 < 0.05) - Performance has improved. -Found 133 outliers among 1000 measurements (13.30%) - 43 (4.30%) high mild - 90 (9.00%) high severe -batch/drain: [growable] power-of-two - time: [1.4447 µs 1.4467 µs 1.4492 µs] - change: [-25.692% -25.022% -24.274%] (p = 0.00 < 0.05) - Performance has improved. -Found 130 outliers among 1000 measurements (13.00%) - 40 (4.00%) high mild - 90 (9.00%) high severe - diff --git a/src/with_alloc/alloc_ringbuffer.rs b/src/with_alloc/alloc_ringbuffer.rs index d579a67..83676d4 100644 --- a/src/with_alloc/alloc_ringbuffer.rs +++ b/src/with_alloc/alloc_ringbuffer.rs @@ -39,8 +39,13 @@ use core::ptr; #[derive(Debug)] pub struct AllocRingBuffer { buf: *mut T, + + // the size of the allocation. Next power of 2 up from the capacity size: usize, + // maximum number of elements actually allowed in the ringbuffer. + // Always less than or equal than the size capacity: usize, + readptr: usize, writeptr: usize, } @@ -291,9 +296,10 @@ impl AllocRingBuffer { Self::new(cap) } - /// Creates a `AllocRingBuffer` with a certain capacity. The capacity must be a power of two. + /// Creates a `AllocRingBuffer` with a certain capacity. The capacity must not be zero. + /// /// # Panics - /// Panics when capacity is zero or not a power of two + /// Panics when capacity is zero #[inline] #[must_use] pub fn new(capacity: usize) -> Self { @@ -312,6 +318,7 @@ impl AllocRingBuffer { } /// Get a reference from the buffer without checking it is initialized. +/// /// Caller must be sure the index is in bounds, or this will panic. #[inline] unsafe fn get_unchecked<'a, T>(rb: *const AllocRingBuffer, index: usize) -> &'a T { @@ -322,6 +329,7 @@ unsafe fn get_unchecked<'a, T>(rb: *const AllocRingBuffer, index: usize) -> & } /// Get a mut reference from the buffer without checking it is initialized. +/// /// Caller must be sure the index is in bounds, or this will panic. #[inline] unsafe fn get_unchecked_mut(rb: *mut AllocRingBuffer, index: usize) -> *mut T { From be752eac4a2f8ebb0f90741309fdaaea2fb08191 Mon Sep 17 00:00:00 2001 From: jdonszelmann Date: Fri, 15 Sep 2023 11:37:33 +0200 Subject: [PATCH 4/5] fix CI --- tests/compile-fail/test_const_generic_array_zero_length_new.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/compile-fail/test_const_generic_array_zero_length_new.rs b/tests/compile-fail/test_const_generic_array_zero_length_new.rs index 24a3494..b080de1 100644 --- a/tests/compile-fail/test_const_generic_array_zero_length_new.rs +++ b/tests/compile-fail/test_const_generic_array_zero_length_new.rs @@ -1,6 +1,6 @@ extern crate ringbuffer; -use ringbuffer::{ConstGenericRingBuffer, RingBufferWrite}; +use ringbuffer::{ConstGenericRingBuffer, RingBuffer}; fn main() { let mut buf = ConstGenericRingBuffer::new::<0>(); From d5edef35cd74762cd20d04479b44109f3bf2ad28 Mon Sep 17 00:00:00 2001 From: jdonszelmann Date: Fri, 15 Sep 2023 11:41:12 +0200 Subject: [PATCH 5/5] fix miri --- src/with_alloc/alloc_ringbuffer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/with_alloc/alloc_ringbuffer.rs b/src/with_alloc/alloc_ringbuffer.rs index 83676d4..71042a0 100644 --- a/src/with_alloc/alloc_ringbuffer.rs +++ b/src/with_alloc/alloc_ringbuffer.rs @@ -151,7 +151,7 @@ impl Drop for AllocRingBuffer { fn drop(&mut self) { self.drain().for_each(drop); - let layout = alloc::alloc::Layout::array::(self.capacity).unwrap(); + let layout = alloc::alloc::Layout::array::(self.size).unwrap(); unsafe { alloc::alloc::dealloc(self.buf as *mut u8, layout); }