public static void MethodCall() { const int loops = 1000000000; int x = 0; ClassB b = new ClassB(); Console.WriteLine("Method Call Overhead:"); Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < loops; i++) { x = x + 2; } watch.Stop(); Report("No function", loops, watch.ElapsedMilliseconds); x -= 2 * loops; watch.Restart(); for (int i = 0; i < loops; i++) { x = b.Func1(x); } watch.Stop(); Report("Non-virtual", loops, watch.ElapsedMilliseconds); x -= 2 * loops; watch.Restart(); for (int i = 0; i < loops; i++) { x = b.Func2(x); } watch.Stop(); Report("override", loops, watch.ElapsedMilliseconds); x -= 2 * loops; watch.Restart(); for (int i = 0; i < loops; i++) { x = b.Func3(x); } watch.Stop(); Report("sealed override", loops, watch.ElapsedMilliseconds); x -= 2 * loops; ClassA a = b; watch.Restart(); for (int i = 0; i < loops; i++) { x = a.Func2(x); } watch.Stop(); Report("virtual via override", loops, watch.ElapsedMilliseconds); x -= 2 * loops; watch.Restart(); for (int i = 0; i < loops; i++) { x = a.Func3(x); } watch.Stop(); Report("Sealed via override", loops, watch.ElapsedMilliseconds); x -= 2 * loops; Console.WriteLine(x); // so the compiler doesn't optimize it away }