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).
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
usesalloc
, just likeAllocRingBuffer
; however, instead of using aVec
, I use aBox
(theVec
stores an additional length argument that is unnecessary if we pre-allocate the capacity). I've modifiedAllocRingBuffer
to have the same optimization.I've also integrated
ModFreeRingBuffer
with the benchmarking system; it beatsAllocRingBuffer<T, NonPowerOfTwo>
, and is very competitive (within 25% of the time taken) forAllocRingBuffer<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).