using System; using System.Diagnostics; using System.Linq; class Benchmark { static Action[] Tests = { LambdaInt32, LambdaString, FakeCachedLambdaInt32, FakeCachedLambdaString, GenericMethodGroupInt32, GenericMethodGroupString, NonGenericMethodGroupInt32, NonGenericMethodGroupString, StaticMethodOnGenericTypeInt32, StaticMethodOnGenericTypeString, InstanceMethodOnGenericTypeInt32, InstanceMethodOnGenericTypeString, }; // Test methods private static void LambdaInt32() { Lambda(); } private static void LambdaString() { Lambda(); } private static void FakeCachedLambdaInt32() { FakeCachedLambda(); } private static void FakeCachedLambdaString() { FakeCachedLambda(); } private static void GenericMethodGroupInt32() { GenericMethodGroup(); } private static void GenericMethodGroupString() { GenericMethodGroup(); } private static void NonGenericMethodGroupInt32() { NonGenericMethodGroup(); } private static void NonGenericMethodGroupString() { NonGenericMethodGroup(); } private static void StaticMethodOnGenericTypeInt32() { StaticMethodOnGenericType(); } private static void StaticMethodOnGenericTypeString() { StaticMethodOnGenericType(); } private static void InstanceMethodOnGenericTypeInt32() { InstanceMethodOnGenericType(); } private static void InstanceMethodOnGenericTypeString() { InstanceMethodOnGenericType(); } // Methods called by the test methods private static void Lambda() { Action foo = () => {}; if (foo == null) { throw new Exception(); } } private static void FakeCachedLambda() { if (FakeLambdaCache.CachedAction == null) { FakeLambdaCache.CachedAction = FakeLambdaCache.NoOp; } Action foo = FakeLambdaCache.CachedAction; if (foo == null) { throw new Exception(); } } private static class FakeLambdaCache { internal static Action CachedAction; internal static void NoOp() {} } private static void GenericMethodGroup() { Action foo = NoOp; if (foo == null) { throw new Exception(); } } private static void NonGenericMethodGroup() { Action foo = NoOp; if (foo == null) { throw new Exception(); } } private static void StaticMethodOnGenericType() { Action foo = SampleGenericClass.NoOpStatic; if (foo == null) { throw new Exception(); } } private static void InstanceMethodOnGenericType() { Action foo = ClassHolder.SampleInstance.NoOpInstance; if (foo == null) { throw new Exception(); } } private static void NoOp() {} private static void NoOp() {} private class ClassHolder { internal static SampleGenericClass SampleInstance = new SampleGenericClass(); } private class SampleGenericClass { internal static void NoOpStatic() { } internal void NoOpInstance() { } } // -------------- INFRASTRUCTURE BELOW HERE -------------- const int Iterations = 10000000; static void Main() { Console.WriteLine("Environment: CLR {0} on {1}", Environment.Version, Environment.OSVersion); // Warm up RunTests(1, false, 0); int maxMethodLength = Tests.Select(x => x.Method.Name.Length).Max(); // Real thing RunTests(Iterations, true, maxMethodLength); } static void RunTests(int count, bool displayResults, int maxLength) { foreach (Action action in Tests) { Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < count; i++) { action(); } sw.Stop(); if (displayResults) { Console.WriteLine("{0}: {1}ms", action.Method.Name.PadRight(maxLength), ((int) sw.ElapsedMilliseconds).ToString().PadLeft(6)); } GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); } } }