static void Main(string[] args) { var argument = Int64.MaxValue.ToString(); var assembly = Assembly.LoadFile(Path.Combine(Environment.CurrentDirectory, "DynamicGenerateCode.dll")); // 找到指定的类型和方法执行 Type type = assembly.GetType("DynamicGenerateCode.Extension"); MethodInfo methodInfo = type.GetMethod("DoWork"); // 代码生成的委托,它负责创建 Extension 示例 Func <object> creationDel = GenerteNewObjDelegate <Func <object> >(type); Func <object, string, bool> doWorkDel = GenerteMethodCallDelegate <Func <object, string, bool> >(methodInfo, type, typeof(bool), new Type[] { typeof(object), typeof(string) }); // 比较运行时间 Console.WriteLine("== 开始示例 =="); const int IterationCount = 10000; Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < IterationCount; i++) { object extensionObject = new TimingDummy(); } watch.Stop(); var elapsedBaseline = watch.ElapsedTicks; Console.WriteLine("Direct ctor: 1.0x"); watch.Start(); for (int i = 0; i < IterationCount; i++) { object extensionObject = Activator.CreateInstance(type); } watch.Stop(); watch.Restart(); for (int i = 0; i < IterationCount; i++) { object extensionObject = creationDel(); } watch.Stop(); Console.WriteLine("Codegen: {0:F1}x", (double)watch.ElapsedTicks / elapsedBaseline); Console.WriteLine(); Console.WriteLine("==METHOD INVOKE=="); var extension = new TimingDummy(); watch.Start(); for (int i = 0; i < IterationCount; i++) { bool result = extension.DoWork(argument); } watch.Stop(); elapsedBaseline = watch.ElapsedTicks; Console.WriteLine("Direct method: 1.0x"); object instance = Activator.CreateInstance(type); watch.Start(); for (int i = 0; i < IterationCount; i++) { bool result = (bool)methodInfo.Invoke(instance, new object[] { argument }); } watch.Stop(); Console.WriteLine("MethodInfo.Invoke: {0:F1}x", (double)watch.ElapsedTicks / elapsedBaseline); object extensionObj = creationDel(); watch.Restart(); for (int i = 0; i < IterationCount; i++) { doWorkDel(extensionObj, argument); } watch.Stop(); Console.WriteLine("Codegen: {0:F1}x", (double)elapsedBaseline / watch.ElapsedTicks); }
static void Main(string[] args) { var argument = Int64.MaxValue.ToString(); // Since we've already taken a dependency on the Extension (as an easy way to get it into the same directory), // this line will load the assembly "without context" and .Net will consider it a completely different assembly. Assembly assembly = Assembly.LoadFile(Path.Combine(Environment.CurrentDirectory, "DynamicLoadExtension.dll")); // Find the type and method we need to execute Type type = assembly.GetType("DynamicLoadExtension.Extension"); MethodInfo methodInfo = type.GetMethod("DoWork"); // Codegen a delegate to create the Extension instance Func <object> creationDel = GenerateNewObjDelegate <Func <object> >(type); Func <object, string, bool> doWorkDel = GenerateMethodCallDelegate <Func <object, string, bool> >(methodInfo, type, typeof(bool), new Type[] { typeof(object), typeof(string) }); // Compare execution times Console.WriteLine("==CREATE INSTANCE=="); const int IterationCount = 100000; Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < IterationCount; i++) { object extensionObject = new TimingDummy(); } watch.Stop(); var elapsedBaseline = watch.ElapsedTicks; Console.WriteLine("Direct ctor: 1.0x"); watch.Start(); for (int i = 0; i < IterationCount; i++) { object extensionObject = Activator.CreateInstance(type); } watch.Stop(); Console.WriteLine("Activator.CreateInstance: {0:F1}x", (double)watch.ElapsedTicks / elapsedBaseline); watch.Restart(); for (int i = 0; i < IterationCount; i++) { object extensionObject = creationDel(); } watch.Stop(); Console.WriteLine("Codegen: {0:F1}x", (double)watch.ElapsedTicks / elapsedBaseline); Console.WriteLine(); Console.WriteLine("==METHOD INVOKE=="); var extension = new TimingDummy(); watch.Start(); for (int i = 0; i < IterationCount; i++) { bool result = extension.DoWork(argument); } watch.Stop(); elapsedBaseline = watch.ElapsedTicks; Console.WriteLine("Direct method: 1.0x"); object instance = Activator.CreateInstance(type); watch.Start(); for (int i = 0; i < IterationCount; i++) { bool result = (bool)methodInfo.Invoke(instance, new object[] { argument }); } watch.Stop(); Console.WriteLine("MethodInfo.Invoke: {0:F1}x", (double)watch.ElapsedTicks / elapsedBaseline); object extensionObj = creationDel(); watch.Restart(); for (int i = 0; i < IterationCount; i++) { doWorkDel(extensionObj, argument); } watch.Stop(); Console.WriteLine("Codegen: {0:F1}x", (double)elapsedBaseline / watch.ElapsedTicks); }