How to efficiently wrap the index of a fixed-size circular buffer

前端 未结 6 986
迷失自我
迷失自我 2021-01-03 04:50

I have a fixed size circular buffer (implemented as an array): upon initialization, the buffer gets filled with the specified maximum number of elements which allows the use

相关标签:
6条回答
  • 2021-01-03 05:07

    FWIW, you could always do a parallel array: i = next[i];

    But, really, I've always just done this: i++; if (i >= n) i = 0; OR i = (i+1) % n;

    Regardless, I'd be really surprised if this is ever a significant performance issue.

    0 讨论(0)
  • 2021-01-03 05:09

    Ensure that the buffer is always a power of two long and mask out the top bits.

    0 讨论(0)
  • 2021-01-03 05:16

    I tested all 3 versions:

    // plain wrap
    public static int WrapIndex(int index, int endIndex, int maxSize)
    {
        return (endIndex + index) > maxSize ? (endIndex + index) - maxSize : endIndex + index;
    }
    
    // wrap using mod
    public static int WrapIndexMod(int index, int endIndex, int maxSize)
    {
        return (endIndex + index) % maxSize;
    }
    
    // wrap by masking out the top bits
    public static int WrapIndexMask(int index, int endIndex, int maxSize)
    {
        return (endIndex + index) & (maxSize - 1);
    }
    

    The performance results (ticks):

    Plain: 25 Mod: 16 Mask: 16 (maxSize = 512)
    Plain: 25 Mod: 17 Mask: 17 (maxSize = 1024)
    Plain: 25 Mod: 17 Mask: 17 (maxSize = 4096)
    

    So it seems that the modulus is the better choice, because it does not require any restriction on the size of the buffer.

    0 讨论(0)
  • 2021-01-03 05:20

    Best I've come up with is:

    public static int Wrap(int index, int n)
    {
        return ((index % n) + n) % n;
    }
    

    (Assuming you need to work with negative numbers)

    0 讨论(0)
  • 2021-01-03 05:21

    It'll depend somewhat on the processor, but it's probably at least worth trying something like return (end_index + index) % buffer_size;

    0 讨论(0)
  • 2021-01-03 05:24
    int GetElement(int index)
    {
        return buffer[(end_index + index) % buffer_size];
    }
    

    See modulo operation for the more information on the modulus operator (%).

    0 讨论(0)
提交回复
热议问题