共用方式為


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);

        }));

    }

}