After asking this question, I decided to write a test and determine the fastest way to wrap an index (where my maxSize
is always a power of 2).
There are 3 functions that I'm comparing:
// 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 my masking out the top bits
public static int WrapIndexMask(int index, int endIndex, int maxSize)
{
return (endIndex + index) & (maxSize - 1);
}
Here is my test:
public static void WrapTest(int numRuns = 10000)
{
int index = 256;
int endIndex = 0;
int maxSize = 4096;
long wrapPlain = 0;
long wrapMod = 0;
long wrapMask = 0;
Stopwatch sw = new Stopwatch();
for (int i = 0; i < numRuns; i++)
{
// plain
sw.Start();
for (int j = 0; j < numRuns; j++)
{
WrapIndex(index, endIndex, maxSize);
}
sw.Stop();
wrapPlain += sw.ElapsedTicks;
sw.Reset();
// mod
sw.Start();
for (int j = 0; j < numRuns; j++)
{
WrapIndexMod(index, endIndex, maxSize);
}
sw.Stop();
wrapMod += sw.ElapsedTicks;
sw.Reset();
// mask
sw.Start();
for (int j = 0; j < numRuns; j++)
{
WrapIndexMask(index, endIndex, maxSize);
}
sw.Stop();
wrapMask += sw.ElapsedTicks;
sw.Reset();
// change indexes
endIndex++;
endIndex = endIndex % maxSize;
index++;
index = index % maxSize;
}
Console.WriteLine(String.Format("Plain: {0} Mod: {1} Mask: {2}", wrapPlain / numRuns, wrapMod / numRuns, wrapMask / numRuns));
}
I ran the test and I'm consistently getting the following results (in 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)
I was expecting that the mask will be faster than all of them, but it seems to be as fast as using the modulo operator. I've also tried increasing the numRuns
, but the results are consistent.
Is my test valid? Is there a better way to test the performance?