From 3bfe04e254317592e8eba1226ed89a776d831226 Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Thu, 8 Jun 2023 19:47:39 +0200 Subject: [PATCH 01/11] README: add table with type properties --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index acb4c6d..860ae6e 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,17 @@ fn main() { ``` +# Comparison of ringbuffer types + +| type | heap allocated | growable | size must be power of 2 | `no_std` | +| ----------------------------------------------|----------------|----------|-------------------------|----------| +| `AllocRingBuffer` | yes | no | yes | no | +| `AllocRingBuffer` | yes | no | no | no | +| `GrowableAllocRingBuffer` | yes | yes | no | no | +| `ConstGenericRingBuffer` | no | no | no[^1] | yes | + +[^1]: Using a size that is not a power of 2 will be ~3x slower. + # Features | name | default | description | From 7e5cceba519a23084a37a45fc7ca93783e3e1370 Mon Sep 17 00:00:00 2001 From: jonay2000 Date: Thu, 8 Jun 2023 20:30:16 +0200 Subject: [PATCH 02/11] add benchmarks --- Cargo.toml | 1 + benches/bench.rs | 11 +++-- benches/comparison.rs | 111 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 benches/comparison.rs diff --git a/Cargo.toml b/Cargo.toml index 6a438cf..875f5e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ license = "MIT" [dev-dependencies] criterion = "0.4.0" compiletest_rs = "0.10.0" +heapless = "0.7.16" [features] default = ["alloc"] diff --git a/benches/bench.rs b/benches/bench.rs index fe85c15..d199a39 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -1,6 +1,9 @@ #![cfg(not(tarpaulin))] use criterion::{black_box, criterion_group, criterion_main, Bencher, Criterion}; use ringbuffer::{AllocRingBuffer, ConstGenericRingBuffer, RingBuffer}; +use crate::comparison::comparison_benches; + +mod comparison; fn benchmark_push, F: Fn() -> T>(b: &mut Bencher, new: F) { b.iter(|| { @@ -112,7 +115,7 @@ fn criterion_benchmark(c: &mut Criterion) { c, AllocRingBuffer, i32, - with_capacity, + new, benchmark_push, 16, 1024, @@ -136,7 +139,7 @@ fn criterion_benchmark(c: &mut Criterion) { c, AllocRingBuffer, i32, - with_capacity, + new, benchmark_various, 16, 1024, @@ -160,7 +163,7 @@ fn criterion_benchmark(c: &mut Criterion) { c, AllocRingBuffer, i32, - with_capacity, + new, benchmark_push_dequeue, 16, 1024, @@ -196,4 +199,4 @@ fn criterion_benchmark(c: &mut Criterion) { } criterion_group!(benches, criterion_benchmark); -criterion_main!(benches); +criterion_main!(benches, comparison_benches); diff --git a/benches/comparison.rs b/benches/comparison.rs new file mode 100644 index 0000000..dfa67b4 --- /dev/null +++ b/benches/comparison.rs @@ -0,0 +1,111 @@ +#![cfg(not(tarpaulin))] + +use std::collections::{LinkedList, VecDeque}; +use std::sync::mpsc::channel; +use criterion::{black_box, criterion_group, Bencher, Criterion}; +use ringbuffer::{AllocRingBuffer, ConstGenericRingBuffer, RingBuffer}; + +const ITER: usize = 1024 * 16; +const CAP: usize = 1024; + +fn std_chan(b: &mut Bencher) { + let (tx, rx) = channel(); + + b.iter(|| { + for i in 0..ITER { + let _ = tx.send(i); + black_box(()); + let res = rx.recv(); + let _ = black_box(res); + } + }); +} + +fn vec(b: &mut Bencher) { + let mut vd = Vec::with_capacity(CAP); + + b.iter(|| { + for i in 0..ITER { + let _ = vd.push(i); + black_box(()); + let res = vd.remove(0); + let _ = black_box(res); + } + }); +} + +fn vecdeque(b: &mut Bencher) { + let mut vd = VecDeque::with_capacity(CAP); + + b.iter(|| { + for i in 0..ITER { + let _ = vd.push_back(i); + black_box(()); + let res = vd.pop_front(); + let _ = black_box(res); + } + }); +} + +fn linked_list(b: &mut Bencher) { + let mut ll = LinkedList::new(); + + b.iter(|| { + for i in 0..ITER { + let _ = ll.push_back(i); + black_box(()); + let res = ll.pop_front(); + let _ = black_box(res); + } + }); +} + +fn cg_rb(b: &mut Bencher) { + let mut rb = ConstGenericRingBuffer::<_, CAP>::new(); + + b.iter(|| { + for i in 0..ITER { + let _ = rb.push(i); + black_box(()); + let res = rb.dequeue(); + let _ = black_box(res); + } + }); +} + +fn heapless_deque(b: &mut Bencher) { + let mut rb = heapless::Deque::<_, CAP>::new(); + + b.iter(|| { + for i in 0..ITER { + let _ = rb.push_back(i); + black_box(()); + let res = rb.pop_front(); + let _ = black_box(res); + } + }); +} + +fn al_rb(b: &mut Bencher) { + let mut rb = AllocRingBuffer::with_capacity_non_power_of_two(CAP); + + b.iter(|| { + for i in 0..10_000 { + let _ = rb.push(i); + black_box(()); + let res = rb.dequeue(); + let _ = black_box(res); + } + }); +} + +fn criterion_benchmark(c: &mut Criterion) { + c.bench_function("comparison std channel", std_chan); + c.bench_function("comparison std vec", vec); + c.bench_function("comparison std vecdeque (growable ringbuffer)", vecdeque); + c.bench_function("comparison const generic ringbuffer", cg_rb); + c.bench_function("comparison alloc ringbuffer", al_rb); + c.bench_function("comparison heapless deque", heapless_deque); +} + +criterion_group!(comparison_benches, criterion_benchmark); From 5348e1759c2e93ad4dfafab0dab2d5774a51c5c9 Mon Sep 17 00:00:00 2001 From: jonay2000 Date: Fri, 9 Jun 2023 09:25:01 +0200 Subject: [PATCH 03/11] add to readme --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 44dcfb9..6f4e035 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,17 @@ fn main() { |-------|---------|--------------------------------------------------------------------------------------------------------------| | alloc | ✓ | Disable this feature to remove the dependency on alloc. Disabling this feature makes `ringbuffer` `no_std`. | +# Comparing with other ringbuffer(-likes) + +To push `10 000` elements to a buffer that was (where possible) pre-sized with a capacity, + +std channel time: [455.65 µs 457.95 µs 460.53 µs] +std vec time: [57.369 µs 57.414 µs 57.458 µs] +std vecdeque (growable ringbuffer) time: [31.816 µs 31.933 µs 32.082 µs] +alloc ringbuffer time: [29.909 µs 29.931 µs 29.955 µs] +heapless deque time: [26.805 µs 26.850 µs 26.910 µs] +const generic ringbuffer time: [18.916 µs 19.141 µs 19.356 µs] + # License Licensed under MIT License From 99e6fd38ab17ff152700397c0de10a8f9632f878 Mon Sep 17 00:00:00 2001 From: jonay2000 Date: Fri, 9 Jun 2023 09:41:50 +0200 Subject: [PATCH 04/11] remove comparison for now --- README.md | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/README.md b/README.md index 6f4e035..44dcfb9 100644 --- a/README.md +++ b/README.md @@ -49,17 +49,6 @@ fn main() { |-------|---------|--------------------------------------------------------------------------------------------------------------| | alloc | ✓ | Disable this feature to remove the dependency on alloc. Disabling this feature makes `ringbuffer` `no_std`. | -# Comparing with other ringbuffer(-likes) - -To push `10 000` elements to a buffer that was (where possible) pre-sized with a capacity, - -std channel time: [455.65 µs 457.95 µs 460.53 µs] -std vec time: [57.369 µs 57.414 µs 57.458 µs] -std vecdeque (growable ringbuffer) time: [31.816 µs 31.933 µs 32.082 µs] -alloc ringbuffer time: [29.909 µs 29.931 µs 29.955 µs] -heapless deque time: [26.805 µs 26.850 µs 26.910 µs] -const generic ringbuffer time: [18.916 µs 19.141 µs 19.356 µs] - # License Licensed under MIT License From 12fed3e42296240d2957f5ee594496d0aedfde31 Mon Sep 17 00:00:00 2001 From: jonay2000 Date: Fri, 9 Jun 2023 10:02:39 +0200 Subject: [PATCH 05/11] benchmarks in the readme --- README.md | 30 ++++++++++++++++++++++++++++-- benches/bench.rs | 2 +- benches/comparison.rs | 20 +++++++++++++++++++- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 860ae6e..dc54603 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Ringbuffer + ![Github Workflows](https://img.shields.io/github/actions/workflow/status/NULLx76/ringbuffer/rust.yml?style=for-the-badge) [![Docs.rs](https://img.shields.io/badge/docs.rs-ringbuffer-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K)](https://docs.rs/ringbuffer) [![Crates.io](https://img.shields.io/crates/v/ringbuffer?logo=rust&style=for-the-badge)](https://crates.io/crates/ringbuffer) @@ -15,13 +16,13 @@ Implementations for three kinds of ringbuffers, with a mostly similar API are pr All of these ringbuffers also implement the RingBuffer trait for their shared API surface. - MSRV: Rust 1.59 # Usage ```rust use ringbuffer::{AllocRingBuffer, RingBuffer, RingBufferExt, RingBufferWrite}; + fn main() { let mut buffer = AllocRingBuffer::with_capacity(2); @@ -46,7 +47,7 @@ fn main() { # Comparison of ringbuffer types | type | heap allocated | growable | size must be power of 2 | `no_std` | -| ----------------------------------------------|----------------|----------|-------------------------|----------| +|-----------------------------------------------|----------------|----------|-------------------------|----------| | `AllocRingBuffer` | yes | no | yes | no | | `AllocRingBuffer` | yes | no | no | no | | `GrowableAllocRingBuffer` | yes | yes | no | no | @@ -54,6 +55,31 @@ fn main() { [^1]: Using a size that is not a power of 2 will be ~3x slower. +## To other ringbuffers + +We ran a benchmark, pushing `10 000` elements to a ringbuffer with a capacity of `1000` (where it was possible to +configure one) to compare +`ringbuffer` to a few common alternatives. +The outcomes show that using the [`ConstGenericRingBuffer`] is about 23 times faster than using an `std::channel` ( +although `ringbuffer` doesn't give the thread safety a channel does). +A maybe more reasonable comparison is to an `std::VecDeque` and `heapless::Deque`, +where ringbuffer is slightly faster as well (among 100 measurements). + +| implementation | time (95% confidence interval, \[lower estimate upper\]) | +|---------------------------------------|----------------------------------------------------------| +| `std::Vec` | `[13.190 ms 13.206 ms 13.223 ms]` | +| `std::LinkedList` | `[225.64 µs 228.09 µs 231.06 µs]` | +| `std::channel` | `[174.86 µs 175.41 µs 176.30 µs]` | +| `std::VecDeque` (growable ringbuffer) | `[33.894 µs 33.934 µs 33.974 µs]` | +| `AllocRingBuffer` | `[30.382 µs 30.451 µs 30.551 µs]` | +| `heapless::Deque` | `[16.260 µs 16.464 µs 16.748 µs]` | +| `ConstGenericRingBuffer` | `[13.685 µs 13.712 µs 13.743 µs]` | + +Note that none of the alternatives to `RingBuffer` have the exact same behavior to `RingBuffer`. All `std` datastructures +compared here can grow unbounded (though in benchmarks they weren't filled over `10 000` elements). + +`heapless::Deque` doesn't drop old items like `ringbuffer` does when the deque is full. Instead, new items aren't let in on push operations. + # Features | name | default | description | diff --git a/benches/bench.rs b/benches/bench.rs index d199a39..3cdf736 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -93,7 +93,7 @@ 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); + let mut rb = AllocRingBuffer::with_capacity_power_of_2(L); for i in 0..1_000_000 { rb.push(i); diff --git a/benches/comparison.rs b/benches/comparison.rs index dfa67b4..3a2018c 100644 --- a/benches/comparison.rs +++ b/benches/comparison.rs @@ -15,6 +15,9 @@ fn std_chan(b: &mut Bencher) { for i in 0..ITER { let _ = tx.send(i); black_box(()); + } + + for i in 0..ITER { let res = rx.recv(); let _ = black_box(res); } @@ -28,6 +31,9 @@ fn vec(b: &mut Bencher) { for i in 0..ITER { let _ = vd.push(i); black_box(()); + } + + for i in 0..ITER { let res = vd.remove(0); let _ = black_box(res); } @@ -41,6 +47,8 @@ fn vecdeque(b: &mut Bencher) { for i in 0..ITER { let _ = vd.push_back(i); black_box(()); + } + for i in 0..ITER { let res = vd.pop_front(); let _ = black_box(res); } @@ -54,6 +62,9 @@ fn linked_list(b: &mut Bencher) { for i in 0..ITER { let _ = ll.push_back(i); black_box(()); + } + + for i in 0..ITER { let res = ll.pop_front(); let _ = black_box(res); } @@ -67,6 +78,8 @@ fn cg_rb(b: &mut Bencher) { for i in 0..ITER { let _ = rb.push(i); black_box(()); + } + for i in 0..ITER { let res = rb.dequeue(); let _ = black_box(res); } @@ -80,6 +93,8 @@ fn heapless_deque(b: &mut Bencher) { for i in 0..ITER { let _ = rb.push_back(i); black_box(()); + } + for i in 0..ITER { let res = rb.pop_front(); let _ = black_box(res); } @@ -90,9 +105,11 @@ fn al_rb(b: &mut Bencher) { let mut rb = AllocRingBuffer::with_capacity_non_power_of_two(CAP); b.iter(|| { - for i in 0..10_000 { + for i in 0..ITER { let _ = rb.push(i); black_box(()); + } + for i in 0..ITER { let res = rb.dequeue(); let _ = black_box(res); } @@ -102,6 +119,7 @@ fn al_rb(b: &mut Bencher) { fn criterion_benchmark(c: &mut Criterion) { c.bench_function("comparison std channel", std_chan); c.bench_function("comparison std vec", vec); + c.bench_function("comparison std linked list", linked_list); c.bench_function("comparison std vecdeque (growable ringbuffer)", vecdeque); c.bench_function("comparison const generic ringbuffer", cg_rb); c.bench_function("comparison alloc ringbuffer", al_rb); From 0bb68be05b5802caf9ebd7cd99eceb0aaa3293df Mon Sep 17 00:00:00 2001 From: jonay2000 Date: Fri, 9 Jun 2023 10:03:26 +0200 Subject: [PATCH 06/11] fmt --- benches/bench.rs | 2 +- benches/comparison.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/benches/bench.rs b/benches/bench.rs index 3cdf736..d24dada 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -1,7 +1,7 @@ #![cfg(not(tarpaulin))] +use crate::comparison::comparison_benches; use criterion::{black_box, criterion_group, criterion_main, Bencher, Criterion}; use ringbuffer::{AllocRingBuffer, ConstGenericRingBuffer, RingBuffer}; -use crate::comparison::comparison_benches; mod comparison; diff --git a/benches/comparison.rs b/benches/comparison.rs index 3a2018c..3bb32ed 100644 --- a/benches/comparison.rs +++ b/benches/comparison.rs @@ -1,9 +1,9 @@ #![cfg(not(tarpaulin))] -use std::collections::{LinkedList, VecDeque}; -use std::sync::mpsc::channel; use criterion::{black_box, criterion_group, Bencher, Criterion}; use ringbuffer::{AllocRingBuffer, ConstGenericRingBuffer, RingBuffer}; +use std::collections::{LinkedList, VecDeque}; +use std::sync::mpsc::channel; const ITER: usize = 1024 * 16; const CAP: usize = 1024; From f6db96400e0def3644c16e8b1abf97dfe5798d9b Mon Sep 17 00:00:00 2001 From: jonay2000 Date: Fri, 9 Jun 2023 10:10:02 +0200 Subject: [PATCH 07/11] fix table --- README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 2c83d63..006632f 100644 --- a/README.md +++ b/README.md @@ -51,14 +51,15 @@ fn main() { # Comparison of ringbuffer types -| type | heap allocated | growable | size must be power of 2 | `no_std` | -|-----------------------------------------------|----------------|----------|-------------------------|----------| -| `AllocRingBuffer` | yes | no | yes | no | -| `AllocRingBuffer` | yes | no | no | no | -| `GrowableAllocRingBuffer` | yes | yes | no | no | -| `ConstGenericRingBuffer` | no | no | no[^1] | yes | +| type | heap allocated | growable | size must be power of 2 | requires alloc[^2] | +|-----------------------------------------------|----------------|----------|-------------------------|--------------------| +| `AllocRingBuffer` | yes | no | yes | yes | +| `AllocRingBuffer` | yes | no | no | yes | +| `GrowableAllocRingBuffer` | yes | yes | no | yes | +| `ConstGenericRingBuffer` | no | no | no[^1] | no | [^1]: Using a size that is not a power of 2 will be ~3x slower. +[^2]: All ringbuffers are `no_std`, but some require an allocator to be available. ## To other ringbuffers From 12490aa3de0a3d50dfdab6468e4a8ef51b01fa60 Mon Sep 17 00:00:00 2001 From: jonay2000 Date: Fri, 9 Jun 2023 10:11:11 +0200 Subject: [PATCH 08/11] fix title --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 006632f..43509d5 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ fn main() { [^1]: Using a size that is not a power of 2 will be ~3x slower. [^2]: All ringbuffers are `no_std`, but some require an allocator to be available. -## To other ringbuffers +## Comparison of other ringbuffers and ringbuffer-like datastructures We ran a benchmark, pushing `10 000` elements to a ringbuffer with a capacity of `1000` (where it was possible to configure one) to compare From b8b6b484d073a68c7c3de1215708e6d9a645cefa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20D=C3=B6nszelmann?= Date: Fri, 9 Jun 2023 10:13:07 +0200 Subject: [PATCH 09/11] Update README.md Co-authored-by: Victor --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 43509d5..9f9db0b 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ fn main() { ## Comparison of other ringbuffers and ringbuffer-like datastructures -We ran a benchmark, pushing `10 000` elements to a ringbuffer with a capacity of `1000` (where it was possible to +We ran a benchmark, pushing `16 384` elements to a ringbuffer with a capacity of `1024` (where it was possible to configure one) to compare `ringbuffer` to a few common alternatives. The outcomes show that using the [`ConstGenericRingBuffer`] is about 23 times faster than using an `std::channel` ( From 72ccd2a40b92c0a05c98cd0fbbeef3dcaaad94e7 Mon Sep 17 00:00:00 2001 From: jonay2000 Date: Fri, 9 Jun 2023 10:16:11 +0200 Subject: [PATCH 10/11] fix number in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f9db0b..612851a 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ where ringbuffer is slightly faster as well (among 100 measurements). | `ConstGenericRingBuffer` | `[13.685 µs 13.712 µs 13.743 µs]` | Note that none of the alternatives to `RingBuffer` have the exact same behavior to `RingBuffer`. All `std` datastructures -compared here can grow unbounded (though in benchmarks they weren't filled over `10 000` elements). +compared here can grow unbounded (though in benchmarks they weren't filled over `65 536` elements). `heapless::Deque` doesn't drop old items like `ringbuffer` does when the deque is full. Instead, new items aren't let in on push operations. From db03cf870c71a958438d8dbee6ba4f273b3cb685 Mon Sep 17 00:00:00 2001 From: jonay2000 Date: Sat, 10 Jun 2023 13:08:06 +0200 Subject: [PATCH 11/11] readme and some comments --- README.md | 6 +++--- src/with_alloc/alloc_ringbuffer.rs | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 612851a..b7d00e2 100644 --- a/README.md +++ b/README.md @@ -88,9 +88,9 @@ compared here can grow unbounded (though in benchmarks they weren't filled over # Features -| name | default | description | -|-------|---------|--------------------------------------------------------------------------------------------------------------| -| alloc | ✓ | Disable this feature to remove the dependency on alloc. Disabling this feature makes `ringbuffer` `no_std`. | +| name | default | description | +|-------|---------|------------------------------------------------------------------------------------------------------------| +| alloc | ✓ | Disable this feature to remove the dependency on alloc. | # License diff --git a/src/with_alloc/alloc_ringbuffer.rs b/src/with_alloc/alloc_ringbuffer.rs index df6f886..7e697cd 100644 --- a/src/with_alloc/alloc_ringbuffer.rs +++ b/src/with_alloc/alloc_ringbuffer.rs @@ -324,6 +324,7 @@ unsafe impl RingBuffer for AllocRingBuffer #[inline] fn fill_with T>(&mut self, mut f: F) { + // This clear is necessary so that the drop methods are called. self.clear(); self.readptr = 0;