• DynamicMethod ILGenerator.Emit


    
    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);
                }
            }
        }
    }
    
    
  • 相关阅读:
    二、Heroku使用教程
    一、Heroku简单介绍
    idea中HTTP Client使用
    在Idea中添加javap命令(反编译)
    Linux中如何记住git密码
    通过flume的hivesink接收数据存到hive数据库表中
    《我想进大厂》之Java基础夺命连环16问
    hive存储json数据
    FreeMarker学习
    arthas-boot.jar使用-代码耗时分析
  • 原文地址:https://www.cnblogs.com/Microshaoft/p/2431638.html
Copyright © 2020-2023  润新知