useless benchmarking
This is admittedly, for the most part, useless, but over a lunch last week I had mentioned writing this out of curiosity and there was a request to post it. As with all benchmarks, if you actually take any numbers this produces as gospel on how to code your application, go get your head checked. :) I was just randomly curious about delegate and params overhead in a particular circumstance.
Upcoming posts will be much more version control related - I promise!
using System;
using System.Diagnostics;
using System.IO;
class RunBenchmark
{
public delegate void BenchmarkMethod();
public static double BenchmarkNanoseconds(int iterationCount, BenchmarkMethod method)
{
// call once before-hand to make sure JIT'ing isn't involved in the real calcs
method();
// now do the timed run
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < iterationCount; i++)
{
method();
}
return 1000*1000*stopwatch.Elapsed.TotalMilliseconds / iterationCount;
}
public static bool IsBitSet(int flags, int checkBit)
{
return (flags & checkBit) == checkBit;
}
public static bool IsBitClear(int flags, int checkBit)
{
return (flags & checkBit) == 0;
}
public static bool AreAllBitsSet(int flags, params int[] checkBits)
{
return Array.TrueForAll(checkBits, delegate(int bit) { return IsBitSet(flags, bit); });
}
public static bool AreAllBitsClear(int flags, params int[] checkBits)
{
return Array.TrueForAll(checkBits, delegate(int bit) { return IsBitClear(flags, bit); });
}
public static bool AreAllBitsSet(int flags, int checkBit)
{
return (flags & checkBit) == checkBit;
}
public static bool AreAllBitsClear(int flags, int checkBit)
{
return (flags & checkBit) == 0;
}
public static bool AreAllBitsSet(int flags, int checkBit1, int checkBit2)
{
int checkBits = checkBit1 & checkBit2;
return (flags & checkBits) == checkBits;
}
public static bool AreAllBitsClear(int flags, int checkBit1, int checkBit2)
{
int checkBits = checkBit1 & checkBit2;
return (flags & checkBits) == 0;
}
static void Main(string[] args)
{
int numRuns = 10 * 1000 * 1000;
Console.WriteLine("empty (delegate overhead): {0:.###} ns", BenchmarkNanoseconds(numRuns, delegate
{
}));
FileAccess access = FileAccess.ReadWrite;
Console.WriteLine("direct check-set: {0:.###} ns", BenchmarkNanoseconds(numRuns, delegate
{
bool foo = (access & FileAccess.Read) != 0;
}));
Console.WriteLine("direct check-clear: {0:.###} ns", BenchmarkNanoseconds(numRuns, delegate
{
bool foo = (access & FileAccess.Read) == 0;
}));
Console.WriteLine("IsBitSet: {0:.###} ns", BenchmarkNanoseconds(numRuns, delegate
{
IsBitSet((int)access, (int)FileAccess.Read);
}));
Console.WriteLine("IsBitClear: {0:.###} ns", BenchmarkNanoseconds(numRuns, delegate
{
IsBitClear((int)access, (int)FileAccess.Read);
}));
Console.WriteLine("AreAllBitsSet (1 param): {0:.###} ns", BenchmarkNanoseconds(numRuns, delegate
{
AreAllBitsSet((int)access, (int)FileAccess.Read);
}));
Console.WriteLine("AreAllBitsClear (1 param): {0:.###} ns", BenchmarkNanoseconds(numRuns, delegate
{
AreAllBitsClear((int)access, (int)FileAccess.Read);
}));
Console.WriteLine("AreAllBitsSet (2 param): {0:.###} ns", BenchmarkNanoseconds(numRuns, delegate
{
AreAllBitsSet((int)access, (int)FileAccess.Read, (int)FileAccess.Write);
}));
Console.WriteLine("AreAllBitsClear (2 param): {0:.###} ns", BenchmarkNanoseconds(numRuns, delegate
{
AreAllBitsClear((int)access, (int)FileAccess.Read, (int)FileAccess.Write);
}));
int[] read = new int[] { (int)FileAccess.Read };
Console.WriteLine("AreAllBitsSet (1 param array): {0:.###} ns", BenchmarkNanoseconds(numRuns, delegate
{
AreAllBitsSet((int)access, read);
}));
Console.WriteLine("AreAllBitsClear (1 param array): {0:.###} ns", BenchmarkNanoseconds(numRuns, delegate
{
AreAllBitsClear((int)access, read);
}));
int[] readAndWrite = new int[] { (int)FileAccess.Read, (int)FileAccess.Write };
Console.WriteLine("AreAllBitsSet (2 param array): {0:.###} ns", BenchmarkNanoseconds(numRuns, delegate
{
AreAllBitsSet((int)access, readAndWrite);
}));
Console.WriteLine("AreAllBitsClear (2 param array): {0:.###} ns", BenchmarkNanoseconds(numRuns, delegate
{
AreAllBitsClear((int)access, readAndWrite);
}));
}
}