优化反射性能的尝试一

最近项目中反射用的很多,担心在性能上会下降太多,所以在下班时间尝试着写了个小例子,来提高反射的性能。

目标:必须支持任意对象类型的目标(Target) 和对象所持有的属性名(PropertyName),能得到对应的属性值

主要思路是将 属性的Get()方法 转换成委托,再把委托存到字典里,需要反射的时候直接去字典里找对应的委托并调用它;

public class Model
    {
        //类初始化的时候就吧Get方法都存好
        public void Init()
        {
            Type type = this.GetType();
            //尝试添加该类到子类列表里,且属性列表不为空
            if (DelegateReflect_TwoDictionary.TypeList.TryAdd(type)&&this.PropertyNames!=null)
            {
                
                //如果添加成功,说明是第一次添加
                ConcurrentDictionary<string, object> Dictionary = new ConcurrentDictionary<string, object>();
                foreach(var item in this.PropertyNames)
                {
                    var GetMethod = DelegateReflect_TwoDictionary.GetPropertyGetMethod(type, item);
                    if (GetMethod != null)
                    {
                        Dictionary.TryAdd(item, GetMethod);
                    }
                }
                DelegateReflect_TwoDictionary.ClassDictionary.TryAdd(type, Dictionary);
            }

        }
        //需要提前获得get委托的属性名列表
        public virtual List<string> PropertyNames
        {
            get { return null; }
        }
    }

    public class A : Model
    {
        public string Name { set; get; }
        public bool Y { set; get; }
        public double[] W { set; get; }
        public override List<string> PropertyNames {
            get{
                return new List<string>(){"Name","Y","W"};
            }
        }
        public A()
        {
            base.Init();
        }

    }
    public class B :Model
    {
        public object Age { set; get; }
        public double X { set; get; }

        public List<int> J { set; get; }
        public Collection<bool> K { set; get; }

        public override List<string> PropertyNames
        {
            get
            {
                return new List<string>() { "Age", "X", "J","K" };
            }
        }
        public B()
        {
            base.Init();
        }
    }
    /// <summary>
    /// 设计模式 模板方法
    /// </summary>
    public abstract class Algorithm {
        //循环次数
        public static int LoopTime;
        public  void TestTime(string AlgorithmName,object Target,string PropertyName)
        {
            this.PreOpration(Target,PropertyName);
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Start();
            for(int i = 0; i < LoopTime; i++)
            {
                ExecuteAlgorithm(Target, PropertyName);
            }
            stopwatch.Stop();
            Console.WriteLine("使用"+AlgorithmName + "执行的时间:" + stopwatch.Elapsed.TotalMilliseconds + "ms");
        }
        //算法测试前的准备(预热)
        public virtual void PreOpration(object Target, string PropertyName)
        {

        }
        //算法正式执行(单次)
        public abstract void ExecuteAlgorithm(object Target,string PropertyName);
    }

    /// <summary>
    /// 反射委托类-双并发字典
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public static class DelegateReflect_TwoDictionary {
        //支持返回值为Double类型的委托
        public delegate double GetDoubleValue<T>(T Target);
        //支持返回值为Double类型的委托
        public delegate int GetIntValue<T>(T Target);
        //支持返回值为对象类型的委托
        public delegate object GetObjectValue<T>(T Target);
        //支持返回值为bool类型的委托
        public delegate bool GetBoolValue<T>(T Target);
        public static BlockingCollection<Type> TypeList = new BlockingCollection<Type>();
        //反射字典,Type是 类的Type
        public static ConcurrentDictionary<Type, ConcurrentDictionary<string, object>> ClassDictionary 
            = new ConcurrentDictionary<Type, ConcurrentDictionary<string, object>>();
        /// <summary>
        /// 反射 只根据 Object和属性名
        /// </summary>
        /// <param name="Target"></param>
        /// <param name="PropertyName"></param>
        /// <returns></returns>
        public static object FastGetValue(object Target, string PropertyName)
        {

            Type TargetType = Target.GetType();
            object get = null;
            ConcurrentDictionary<string, object> PropertyDictionary = null;
            if (!ClassDictionary.TryGetValue(TargetType, out PropertyDictionary))
            {
                PropertyDictionary = new ConcurrentDictionary<string, object>();
                ClassDictionary.TryAdd(TargetType, PropertyDictionary);
            }
            if (!PropertyDictionary.TryGetValue(PropertyName, out get))
            {
                PropertyInfo propertyInfo = TargetType.GetProperty(PropertyName);
                MethodInfo GetMethod = propertyInfo.GetGetMethod();
                Type DelegateType = null;
                if (propertyInfo.PropertyType == typeof(int))
                {
                    //动态指定泛型的类型
                    DelegateType = typeof(GetIntValue<>).MakeGenericType(TargetType);

                }
                else if (propertyInfo.PropertyType == typeof(double))
                {
                    //动态指定泛型的类型
                    DelegateType = typeof(GetDoubleValue<>).MakeGenericType(TargetType);
                }
                else if (propertyInfo.PropertyType == typeof(bool))
                {
                    //动态指定泛型的类型
                    DelegateType = typeof(GetBoolValue<>).MakeGenericType(TargetType);
                }
                else
                {
                    //动态指定泛型的类型
                    DelegateType = typeof(GetObjectValue<>).MakeGenericType(TargetType);
                }
                get = Delegate.CreateDelegate(DelegateType, GetMethod);
                PropertyDictionary.TryAdd(PropertyName, get);
            }
            dynamic x = get;
            dynamic y = Target;
            return x(y);
        }
        //获得某个属性的Get方法
        public static object GetPropertyGetMethod(Type TargetType,string PropertyName)
        {
            PropertyInfo propertyInfo = TargetType.GetProperty(PropertyName);
            object get = null;
            if (propertyInfo != null && propertyInfo.CanRead)
            {
                MethodInfo GetMethod = propertyInfo.GetGetMethod();
                Type DelegateType = null;
                if (propertyInfo.PropertyType == typeof(int))
                {
                    //动态指定泛型的类型
                    DelegateType = typeof(GetIntValue<>).MakeGenericType(TargetType);

                }
                else if (propertyInfo.PropertyType == typeof(double))
                {
                    //动态指定泛型的类型
                    DelegateType = typeof(GetDoubleValue<>).MakeGenericType(TargetType);
                }
                else if (propertyInfo.PropertyType == typeof(bool))
                {
                    //动态指定泛型的类型
                    DelegateType = typeof(GetBoolValue<>).MakeGenericType(TargetType);
                }
                else
                {
                    //动态指定泛型的类型
                    DelegateType = typeof(GetObjectValue<>).MakeGenericType(TargetType);
                }
                get = Delegate.CreateDelegate(DelegateType, GetMethod);
            }
            return get;
        }

    }
    /// <summary>
    /// 反射委托类-单并发字典
    /// </summary>
    
    //委托反射
    public class DelegateAlgorithm_TwoDictionary : Algorithm {
        public override void PreOpration(object Target, string PropertyName)
        {
            //  var result = DelegateReflect_TwoDictionary.FastGetValue(Target, PropertyName);
        }
        public override void ExecuteAlgorithm(object Target, string PropertyName)
        {
            var result = DelegateReflect_TwoDictionary.FastGetValue(Target, PropertyName);
        }
    }
    //直接调用
    public class StraightInvoke : Algorithm {
        public override void ExecuteAlgorithm(object Target, string PropertyName)
        {
            var result = ((A)Target).Name;
        }
    }
    //纯反射
    public class Reflect : Algorithm
    {
        public override void ExecuteAlgorithm(object Target, string PropertyName)
        {
            Type type = Target.GetType();
            PropertyInfo property = type.GetProperty(PropertyName);
            if (property != null&&property.CanRead)
            {
                var result = property.GetValue(Target);
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Algorithm.LoopTime = 1000;
            A a = new A() { Name = "fangxiang",Y=true,W=new double[4] };
            B b = new B() { Age = 1 ,X=2};

            Algorithm Delegate = new DelegateAlgorithm_TwoDictionary();
            Delegate.TestTime("委托反射-双字典",a,"Name");
            Delegate.TestTime("委托反射-双字典", a, "Y");
            Delegate.TestTime("委托反射-双字典", a, "W");
            Delegate.TestTime("委托反射-双字典", b, "Age");
            Delegate.TestTime("委托反射-双字典", b, "X");
            Delegate.TestTime("委托反射-双字典", b, "J");
            Delegate.TestTime("委托反射-双字典", b, "K");

            Algorithm Reflect = new Reflect();
           Reflect.TestTime("纯反射", a, "Name");
            Reflect.TestTime("纯反射", a, "Y");
            Reflect.TestTime("纯反射", a, "W");
            Reflect.TestTime("纯反射", b, "Age");
            Reflect.TestTime("纯反射", b, "X");
            Reflect.TestTime("纯反射", b, "J");
            Reflect.TestTime("纯反射", b, "K");
            Algorithm StraightInvoke = new StraightInvoke();

            
            Console.ReadKey();
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值