zoukankan      html  css  js  c++  java
  • DynamicMethodHelper R2 20120814 DynamicMethod ILGenerator.Emit

    
    namespace ConsoleApplication
    {
        using System;
        using System.Diagnostics;
        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.Runtime.InteropServices;
        using System.Threading;
        using System.Threading.Tasks;
        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.Linq;
        using System.Reflection;
        using System.Reflection.Emit;
        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 parametersInfos = methodInfo.GetParameters();
                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;
                Array.ForEach
                        (
                            parametersInfos
                            , (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);
                }
            }
        }
    }
    
    
  • 相关阅读:
    【xsy2506】 bipartite 并查集+线段树
    Linux K8s容器集群技术
    Linux 运维工作中的经典应用ansible(批量管理)Docker容器技术(环境的快速搭建)
    Linux Django项目部署
    Linux Django项目测试
    Linux 首先基本包安装(vim啊什么的),源,源优化,项目架构介绍, (LNMuWsgi)Django项目相关软件mysql,redies,python(相关模块)安装配置测试
    Linux centos系统安装后的基本配置,Linux命令
    Linux 虚拟机上安装linux系统 (ip:子网掩码,网关,dns,交换机,路由知识回顾)
    $ Django 调API的几种方式,django自定义错误响应
    $Django 路飞之显示视频,Redis存购物车数据,优惠卷生成表,优惠卷的一个领取表。(知识小回顾)
  • 原文地址:https://www.cnblogs.com/Microshaoft/p/2637254.html
Copyright © 2011-2022 走看看