NULLx76 / ringbuffer

A fixed-size circular buffer written in Rust.
https://crates.io/crates/ringbuffer
MIT License
95 stars 20 forks source link

A faster non-power-of-two ring buffer #79

Closed thedmm closed 1 year ago

thedmm commented 1 year ago

I've implemented my own RingBuffer, ModFreeRingBuffer, that uses conditional subtraction instead of expensive modulo operations. It maintains a base index that is kept within a fixed range of the buffer, and is conditionally subtracted as necessary. When used in a loop, the compiler is able to optimize the involved branches quite effectively.

ModFreeRingBuffer uses alloc, just like AllocRingBuffer; however, instead of using a Vec, I use a Box (the Vec stores an additional length argument that is unnecessary if we pre-allocate the capacity). I've modified AllocRingBuffer to have the same optimization.

I've also integrated ModFreeRingBuffer with the benchmarking system; it beats AllocRingBuffer<T, NonPowerOfTwo>, and is very competitive (within 25% of the time taken) for AllocRingBuffer<T, PowerOfTwo>. It can definitely be tuned further (for example, pointers can be used instead of indices, or indices can use units of bytes instead of elements).