namespace ConsoleApplication { using System; using System.Reflection; using System.Reflection.Emit; using System.Collections.Generic; //using System.Text; using System.Linq; using System.Diagnostics; //using System.Linq.Expressions; using Microshaoft; /// <summary> /// Class1 的摘要说明。 /// </summary> public class Class1 { /// <summary> /// 应用程序的主入口点。 /// </summary> //[STAThread] static void Main(string[] args) { Person person = new Person(); string word = "hello"; Person p = null; object[] param = new object[] { word, p, 3 }; Stopwatch watch1 = new Stopwatch(); //FastInvokeHandler fastInvoker = DynamicMethodHelper.GetDynamicMethodInvoker(methodInfo); Person x = null; int y = -1; DynamicMethodHelper.DynamicMethodFuncInvokeHandler handler1 = DynamicMethodHelper.GetDynamicMethodFuncInvoker ( person , mi => { return !mi.IsStatic && mi.Name.Equals("Say"); } ); DynamicMethodHelper.DynamicMethodFuncInvokeHandler handler2 = DynamicMethodHelper.GetDynamicMethodFuncInvoker<Person> ( mi => { return mi.IsStatic && mi.Name.Equals("Say"); } );//.Invoke(person, new object[] { "hihi" }); CodeTimer.Time ( "串行测试" , 1 , () => { var parameters = new object[] { "aaa", x, y }; handler1.DynamicInvoke(person, parameters); Console.WriteLine("实例方法 Say Invoke ref word: {0}, int avi {1}", parameters[0], parameters[2]); handler1.Invoke(person, parameters); Console.WriteLine("实例方法 Say Invoke ref word: {0}, int avi {1}", parameters[0], parameters[2]); string s = (string)handler2.DynamicInvoke(person, new object[] { "bb", x, y }); Console.WriteLine("静态方法 Say DynamicInvoke return: {0}", s); s = (string)handler2.Invoke(person, new object[] { "bb", x, y }); Console.WriteLine("静态方法 Say Invoke return: {0}", s); } ); CodeTimer.ParallelTime ( "并行测试" , 1 , () => { var parameters = new object[] { "aaa", x, y }; handler1.DynamicInvoke(person, parameters); Console.WriteLine("实例方法 Say Invoke ref word: {0}, int avi {1}", parameters[0], parameters[2]); handler1.Invoke(person, parameters); Console.WriteLine("实例方法 Say Invoke ref word: {0}, int avi {1}", parameters[0], parameters[2]); string s = (string)handler2.DynamicInvoke(person, new object[] { "bb", x, y }); Console.WriteLine("静态方法 Say DynamicInvoke return: {0}", s); s = (string)handler2.Invoke(person, new object[] { "bb", x, y }); Console.WriteLine("静态方法 Say Invoke return: {0}", s); } ); Console.ReadLine(); } } public class Person { public void Say(ref string word, out Person p, int avi) { word = "instance " + avi.ToString(); //Console.WriteLine(word); p = new Person(); //return 100; } public static string Say(string word) { //Console.WriteLine("Static Say"); return "return static " + word; } } } namespace Microshaoft { using System; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using System.Runtime.InteropServices; public static class CodeTimer { public static void Initialize() { Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High; Thread.CurrentThread.Priority = ThreadPriority.Highest; Time("", 1, () => { }); } public static void ParallelTime(string name, int iteration, Action action) { InternalIterationProcess ( name , iteration , () => { Parallel.For ( 0 , iteration , new ParallelOptions() { MaxDegreeOfParallelism = 4, TaskScheduler = null } , i => { action(); } ); } ); } private static void InternalIterationProcess(string name, int iteration, Action action) { if (string.IsNullOrEmpty(name)) { return; } // 1. ConsoleColor currentForeColor = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine(name); // 2. GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); int[] gcCounts = new int[GC.MaxGeneration + 1]; for (int i = 0; i <= GC.MaxGeneration; i++) { gcCounts[i] = GC.CollectionCount(i); } // 3. Stopwatch watch = new Stopwatch(); watch.Start(); ulong cycleCount = GetCycleCount(); action(); ulong cpuCycles = GetCycleCount() - cycleCount; watch.Stop(); // 4. Console.ForegroundColor = currentForeColor; Console.WriteLine("\tTime Elapsed:\t" + watch.ElapsedMilliseconds.ToString("N0") + "ms"); Console.WriteLine("\tCPU Cycles:\t" + cpuCycles.ToString("N0")); // 5. for (int i = 0; i <= GC.MaxGeneration; i++) { int count = GC.CollectionCount(i) - gcCounts[i]; Console.WriteLine("\tGen " + i + ": \t\t" + count); } Console.WriteLine(); } public static void Time(string name, int iteration, Action action) { InternalIterationProcess ( name , iteration , () => { for (int i = 0; i < iteration; i++) { action(); } } ); } private static ulong GetCycleCount() { ulong cycleCount = 0; QueryThreadCycleTime(GetCurrentThread(), ref cycleCount); return cycleCount; } [DllImport("kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool QueryThreadCycleTime(IntPtr threadHandle, ref ulong cycleTime); [DllImport("kernel32.dll")] static extern IntPtr GetCurrentThread(); } } namespace Microshaoft { using System; using System.Reflection; using System.Reflection.Emit; using System.Collections.Generic; using System.Text; using System.Linq; using System.Diagnostics; public class DynamicMethodHelper { public delegate object DynamicMethodFuncInvokeHandler(object target, object[] parameters); public static DynamicMethodFuncInvokeHandler GetDynamicMethodFuncInvoker(string typeName, Func<MethodInfo, bool> predicateFunc) { MethodInfo methodInfo = Type.GetType(typeName).GetMethods().First ( mi => { return predicateFunc(mi); } ); DynamicMethod dynamicMethod = GetDynamicMethod(methodInfo); return (DynamicMethodFuncInvokeHandler)dynamicMethod.CreateDelegate(typeof(DynamicMethodFuncInvokeHandler)); } public static DynamicMethodFuncInvokeHandler GetDynamicMethodFuncInvoker<TTarget>(Func<MethodInfo, bool> predicateFunc) { MethodInfo methodInfo = typeof(TTarget).GetMethods().First ( mi => { return predicateFunc(mi); } ); DynamicMethod dynamicMethod = GetDynamicMethod(methodInfo); return (DynamicMethodFuncInvokeHandler)dynamicMethod.CreateDelegate(typeof(DynamicMethodFuncInvokeHandler)); } public static DynamicMethodFuncInvokeHandler GetDynamicMethodFuncInvoker(object target, Func<MethodInfo, bool> predicateFunc) { MethodInfo methodInfo = target.GetType().GetMethods().First ( mi => { return predicateFunc(mi); } ); DynamicMethod dynamicMethod = GetDynamicMethod(methodInfo); return (DynamicMethodFuncInvokeHandler)dynamicMethod.CreateDelegate(typeof(DynamicMethodFuncInvokeHandler)); } private static DynamicMethod GetDynamicMethod(MethodInfo methodInfo) { int i = 0; var list = methodInfo.GetParameters().ToList(); DynamicMethod dynamicMethod = new DynamicMethod ( string.Empty , typeof(object) , new Type[] { typeof(object) , typeof(object[]) } , methodInfo.DeclaringType.Module ); ILGenerator ilg = dynamicMethod.GetILGenerator(); if (!methodInfo.IsStatic) { ilg.Emit(OpCodes.Ldarg_0); } i = 0; list.ForEach ( pi => { Type pt; if (pi.ParameterType.IsByRef) { pt = pi.ParameterType.GetElementType(); } else { pt = pi.ParameterType; } //paramTypes[i] = pt; LocalBuilder lb = ilg.DeclareLocal(pt, true); ilg.Emit(OpCodes.Ldarg_1); EmitFastInt(ilg, i); ilg.Emit(OpCodes.Ldelem_Ref); EmitCastToReference(ilg, pt); ilg.Emit(OpCodes.Stloc, lb); if (pi.ParameterType.IsByRef) { ilg.Emit(OpCodes.Ldloca_S, lb); ilg.Emit(OpCodes.Ldarg_1); EmitFastInt(ilg, i); ilg.Emit(OpCodes.Ldloc, lb); if (lb.LocalType.IsValueType) { ilg.Emit(OpCodes.Box, lb.LocalType); } ilg.Emit(OpCodes.Stelem_Ref); } else { ilg.Emit(OpCodes.Ldloc, lb); } i++; } ); if (methodInfo.IsStatic) { ilg.EmitCall(OpCodes.Call, methodInfo, null); } else { ilg.EmitCall(OpCodes.Callvirt, methodInfo, null); } if (methodInfo.ReturnType == typeof(void)) { ilg.Emit(OpCodes.Ldnull); } else { EmitBoxIfNeeded(ilg, methodInfo.ReturnType); } ilg.Emit(OpCodes.Ret); return dynamicMethod; } private static void EmitCastToReference(ILGenerator ilg, Type type) { if (type.IsValueType) { ilg.Emit(OpCodes.Unbox_Any, type); } else { ilg.Emit(OpCodes.Castclass, type); } } private static void EmitBoxIfNeeded(ILGenerator ilg, Type type) { if (type.IsValueType) { ilg.Emit(OpCodes.Box, type); } } private static void EmitFastInt(ILGenerator il, int value) { switch (value) { case -1: il.Emit(OpCodes.Ldc_I4_M1); return; case 0: il.Emit(OpCodes.Ldc_I4_0); return; case 1: il.Emit(OpCodes.Ldc_I4_1); return; case 2: il.Emit(OpCodes.Ldc_I4_2); return; case 3: il.Emit(OpCodes.Ldc_I4_3); return; case 4: il.Emit(OpCodes.Ldc_I4_4); return; case 5: il.Emit(OpCodes.Ldc_I4_5); return; case 6: il.Emit(OpCodes.Ldc_I4_6); return; case 7: il.Emit(OpCodes.Ldc_I4_7); return; case 8: il.Emit(OpCodes.Ldc_I4_8); return; } if (value > -129 && value < 128) { il.Emit(OpCodes.Ldc_I4_S, (SByte)value); } else { il.Emit(OpCodes.Ldc_I4, value); } } } } |