static void Main(string[] args) { var foo = new FooImpl(); var iFoo = (IFoo)foo; Func <int> directLambda = () => foo.Bar(); Func <int> virtualLambda = () => iFoo.Bar(); var directCall = CompileBar(foo, asInterfaceCall: false); var virtualCall = CompileBar(foo, asInterfaceCall: true); var iterationCount = 200000000; var sw = Stopwatch.StartNew(); for (int i = 0; i < iterationCount; i++) { virtualCall(); } var elapsedMs = sw.ElapsedMilliseconds; Console.WriteLine($"Compiled Virtual Call: {elapsedMs} ms"); sw.Restart(); for (int i = 0; i < iterationCount; i++) { directCall(); } elapsedMs = sw.ElapsedMilliseconds; Console.WriteLine($"Compiled Direct Call: {elapsedMs} ms"); sw.Restart(); for (int i = 0; i < iterationCount; i++) { virtualLambda(); } elapsedMs = sw.ElapsedMilliseconds; Console.WriteLine($"Lambda Virtual Call: {elapsedMs} ms"); sw.Restart(); for (int i = 0; i < iterationCount; i++) { directLambda(); } elapsedMs = sw.ElapsedMilliseconds; Console.WriteLine($"Lambda Direct Call: {elapsedMs} ms"); sw.Restart(); for (int i = 0; i < iterationCount; i++) { iFoo.Bar(); } elapsedMs = sw.ElapsedMilliseconds; Console.WriteLine($"Virtual Call: {elapsedMs} ms"); sw.Restart(); for (int i = 0; i < iterationCount; i++) { foo.Bar(); } elapsedMs = sw.ElapsedMilliseconds; Console.WriteLine($"Direct Call: {elapsedMs} ms"); }
static void Main(string[] args) { var foo = new FooImpl(); var iFoo = (IFoo)foo; Func <int> directLambda = () => foo.Bar(); Func <int> virtualLambda = () => iFoo.Bar(); var compiledDirectCall = CompileBar(foo, asInterfaceCall: false); var compiledVirtualCall = CompileBar(foo, asInterfaceCall: true); var compiledArgDirectCall = CompileBar <FooImpl>(); var compiledArgVirtualCall = CompileBar <IFoo>(); var barMethodInfo = typeof(FooImpl).GetMethod(nameof(FooImpl.Bar)); var iBarMethodInfo = typeof(IFoo).GetMethod(nameof(IFoo.Bar)); var compiledToModuleDirect = CompileToModule <FooImpl>(); var compiledToModuleVirtual = CompileToModule <IFoo>(); var iterationCount = 200000000; var sw = Stopwatch.StartNew(); for (int i = 0; i < iterationCount; i++) { compiledVirtualCall(); } var elapsedMs = sw.ElapsedMilliseconds; Console.WriteLine($"Compiled Virtual Call: {elapsedMs} ms"); sw.Restart(); for (int i = 0; i < iterationCount; i++) { compiledDirectCall(); } elapsedMs = sw.ElapsedMilliseconds; Console.WriteLine($"Compiled Direct Call: {elapsedMs} ms"); sw.Restart(); for (int i = 0; i < iterationCount; i++) { compiledArgVirtualCall(iFoo); } elapsedMs = sw.ElapsedMilliseconds; Console.WriteLine($"Compiled w/ Arg Virtual Call: {elapsedMs} ms"); sw.Restart(); for (int i = 0; i < iterationCount; i++) { compiledArgDirectCall(foo); } elapsedMs = sw.ElapsedMilliseconds; Console.WriteLine($"Compiled w/ Arg Direct Call: {elapsedMs} ms"); sw.Restart(); for (int i = 0; i < iterationCount; i++) { compiledToModuleVirtual(iFoo); } elapsedMs = sw.ElapsedMilliseconds; Console.WriteLine($"Dynamic Module Virtual Call: {elapsedMs} ms"); sw.Restart(); for (int i = 0; i < iterationCount; i++) { compiledToModuleDirect(foo); } elapsedMs = sw.ElapsedMilliseconds; Console.WriteLine($"Dynamic Module Direct Call: {elapsedMs} ms"); sw.Restart(); for (int i = 0; i < iterationCount; i++) { virtualLambda(); } elapsedMs = sw.ElapsedMilliseconds; Console.WriteLine($"Code Lambda Virtual Call: {elapsedMs} ms"); sw.Restart(); for (int i = 0; i < iterationCount; i++) { directLambda(); } elapsedMs = sw.ElapsedMilliseconds; Console.WriteLine($"Code Lambda Direct Call: {elapsedMs} ms"); sw.Restart(); for (int i = 0; i < iterationCount; i++) { iFoo.Bar(); } elapsedMs = sw.ElapsedMilliseconds; Console.WriteLine($"Virtual Call: {elapsedMs} ms"); sw.Restart(); for (int i = 0; i < iterationCount; i++) { foo.Bar(); } elapsedMs = sw.ElapsedMilliseconds; Console.WriteLine($"Direct Call: {elapsedMs} ms"); sw.Restart(); for (int i = 0; i < iterationCount; i++) { int result = (int)iBarMethodInfo.Invoke(iFoo, null); } elapsedMs = sw.ElapsedMilliseconds; Console.WriteLine($"Reflection Virtual Call: {elapsedMs} ms"); sw.Restart(); for (int i = 0; i < iterationCount; i++) { int result = (int)barMethodInfo.Invoke(foo, null); } elapsedMs = sw.ElapsedMilliseconds; Console.WriteLine($"Reflection Direct Call: {elapsedMs} ms"); }