zoukankan      html  css  js  c++  java
  • 使用DynamicMethod替代反射,提高100倍的性能!(附源码)

    ------------------

    前言

    ------------------ 

    反射性能实在是太恶劣,在通讯系统、数据库系统中已经无法忍受了。于是我在codeproject上找到一篇使用DynamicMethod的替代方法。http://www.codeproject.com/KB/cs/Dynamic_Code_Generation.aspx

    可是作者实在也太简陋了,目前仅支持FIeld / Property,于是我扩展了。

    1.支持FIeld / 带参数Constructor / Property / Index 

    2.操作过程和反射过程一摸一样。

    ------------------

    代码测试结果 

    ------------------

    测试对象:

    代码
    class SomeClass
        {
            
    public int name;
            
    public string sname;

            
    public SomeClass()
            {
            }
            
    public SomeClass(string name)
            {
                
    this.sname = name;

            }

            
    public int Name
            {
                
    get { return name; }
                
    set { name = value; }
            }
            
    public string Sname
            {
                
    get { return sname; }
                
    set { sname = value; }
            }
            
    public string this[int index, string name, int a, int b, string c, double d]
            {
                
    get
                {
                    
    return index.ToString() + name;
                }
                
    set
                {
                }
            }
        }

    SetFIeld的反射 VS 动态编译

    代码
            //set field
            public void test003()
            {
                SomeClass c 
    = new SomeClass();

                FieldInfo field 
    = c.GetType().GetFields()[1];

                StartTest(
    "begin reflection.");

                
    for (int i = 0; i < 10000000; i++)
                {
                    field.SetValue(c, 
    "test");
                }

                EndTest(
    "end reflection");

                IDynamicFieldInfo dfield 
    = new DynamicType(c.GetType()).GetFields()[1];

                StartTest(
    "begin dynamic.");

                
    for (int i = 0; i < 10000000; i++)
                {
                    dfield.SetValue(c, 
    "test");
                }

                EndTest(
    "end dynamic");
            }

    测试结果:

    代码
    ------ Test started: Assembly: Pixysoft.Framework.Reflection.dll ------

    begin reflection.
    end reflection
    00:00:28.3593750

    begin dynamic.
    end dynamic
    00:00:00.2500000


    1 passed, 0 failed, 0 skipped, took 28.70 seconds (Ad hoc).

    性能提高100多倍。

    GetFIeld  反射VS动态编译

    代码
    public void test004()
            {
                SomeClass c 
    = new SomeClass();

                FieldInfo field 
    = c.GetType().GetFields()[1];

                StartTest(
    "begin reflection.");

                field.SetValue(c, 
    "test");

                
    for (int i = 0; i < 10000000; i++)
                {
                    field.GetValue(c);
                }

                EndTest(
    "end reflection");




                IDynamicFieldInfo dfield 
    = new DynamicType(c.GetType()).GetFields()[1];

                dfield.SetValue(c, 
    "test");

                StartTest(
    "begin dynamic.");

                
    for (int i = 0; i < 10000000; i++)
                {
                    dfield.GetValue(c);
                }

                EndTest(
    "end dynamic");
            }

    测试结果

    代码
    ------ Test started: Assembly: Pixysoft.Framework.Reflection.dll ------

    begin reflection.
    end reflection
    00:00:18.9531250

    begin dynamic.
    end dynamic
    00:00:00.2031250


    1 passed, 0 failed, 0 skipped, took 19.25 seconds (Ad hoc).

    提高接近100倍

    GetProperty 反射VS动态编译

    代码
    public void test006()
            {
                SomeClass c 
    = new SomeClass();

                PropertyInfo property 
    = c.GetType().GetProperties()[1];

                StartTest(
    "begin reflection.");

                
    for (int i = 0; i < 1000000; i++)
                {
                    property.GetValue(c, 
    null);
                }

                EndTest(
    "end reflection");




                IDynamicPropertyInfo dproperty 
    = new DynamicType(c.GetType()).GetProperties()[1];

                StartTest(
    "begin dynamic.");

                
    for (int i = 0; i < 1000000; i++)
                {
                    dproperty.GetValue(c, 
    null);
                }

                EndTest(
    "end dynamic");
            }

    测试结果 

    代码
    ------ Test started: Assembly: Pixysoft.Framework.Reflection.dll ------

    begin reflection.
    end reflection
    00:00:05.5312500

    begin dynamic.
    end dynamic
    00:00:00.0468750


    1 passed, 0 failed, 0 skipped, took 5.66 seconds (Ad hoc).

    依然100倍!!! 

    SetProperty 反射VS动态编译

    代码
    public void test005()
            {
                SomeClass c 
    = new SomeClass();

                PropertyInfo property 
    = c.GetType().GetProperties()[0];

                StartTest(
    "begin reflection.");

                
    for (int i = 0; i < 1000000; i++)
                {
                    property.SetValue(c, i, 
    null);
                }

                EndTest(
    "end reflection");

                IDynamicPropertyInfo dproperty 
    = new DynamicType(c.GetType()).GetProperties()[0];

                StartTest(
    "begin dynamic.");

                
    for (int i = 0; i < 1000000; i++)
                {
                    dproperty.SetValue(c, i, 
    null);
                }

                EndTest(
    "end dynamic");
            }

     测试结果 

    代码
    ------ Test started: Assembly: Pixysoft.Framework.Reflection.dll ------

    begin reflection.
    end reflection
    00:00:09.0625000

    begin dynamic.
    end dynamic
    00:00:00.0468750


    1 passed, 0 failed, 0 skipped, took 9.20 seconds (Ad hoc).

    遥遥领先250倍

    Constructor 反射VS动态编译 

    代码
    public void test008()
            {
                Type type 
    = typeof(SomeClass);

                StartTest(
    "begin reflection.");

                
    for (int i = 0; i < 1000000; i++)
                {
                    
    object result = Activator.CreateInstance(type, "hello");
                }

                EndTest(
    "end reflection");


                StartTest(
    "begin dynamic.");

                IDynamicConstructorInfo dConstructorInfo 
    = new DynamicType(type).GetConstructors()[1];

                
    for (int i = 0; i < 1000000; i++)
                {
                    
    object result = dConstructorInfo.Invoke(new object[] { "hello" });
                }

                EndTest(
    "end dynamic");


                StartTest(
    "begin dynamic.");

                
    for (int i = 0; i < 1000000; i++)
                {
                    
    object result = new DynamicType(type).GetConstructors()[1].Invoke(new object[] { "hello" });
                }

                EndTest(
    "end dynamic");
            } 

    测试结果 

    代码
    ------ Test started: Assembly: Pixysoft.Framework.Reflection.dll ------

    begin reflection.
    end reflection
    00:00:07.5937500

    begin dynamic.
    end dynamic
    00:00:00.1250000

    begin dynamic.
    end dynamic
    00:00:01.2187500


    1 passed, 0 failed, 0 skipped, took 9.02 seconds (Ad hoc).

    60倍左右。

    GetIndex 反射VS动态编译

    代码
    public void test007()
            {
                SomeClass c 
    = new SomeClass();

                Type type 
    = c.GetType();

                PropertyInfo property 
    = type.GetProperties()[2];

                StartTest(
    "begin reflection.");

                
    for (int i = 0; i < 1000000; i++)
                {
                    property.SetValue(c, i.ToString(), 
    new object[] { 0""00""0 });
                }

                EndTest(
    "end reflection");

                IDynamicPropertyInfo dproperty 
    = new DynamicType(type).GetProperties()[2];

                StartTest(
    "begin dynamic.");

                
    for (int i = 0; i < 1000000; i++)
                {
                    dproperty.SetValue(c, i.ToString(), 
    new object[] { 0""00"", (double)0 });
                }

                EndTest(
    "end dynamic");


                StartTest(
    "begin dynamic set property.");

                
    for (int i = 0; i < 1000000; i++)
                {
                    
    new DynamicType(type).GetProperties()[2].SetValue(c, i.ToString(), new object[] { 0""00"", (double)0 });
                }

                EndTest(
    "end dynamic");
            }

    测试结果 

    代码
    ------ Test started: Assembly: Pixysoft.Framework.Reflection.dll ------

    begin reflection.
    end reflection
    00:00:07.2656250

    begin dynamic.
    end dynamic
    00:00:00.5000000

    begin dynamic 
    set property.
    end dynamic
    00:00:01.7968750


    1 passed, 0 failed, 0 skipped, took 9.64 seconds (Ad hoc).

    30倍左右(性能损失在了装箱拆箱) 

    ----------------------

    源码下载与备注

    ----------------------

    http://www.boxcn.net/shared/8qqgob51hi

    空间由boxcn.net提供,放心下载。

    开始的时候,想到老赵的反射开源,可是他用Linq去实现,在dotnet 2.0不支持,而现状是大部分服务器应用还是dotnet 2.0, 只好放弃。

    之后codeproject找到了篇文章介绍了DynamicMethod,可是作者写的比较龊,于是我稍微扩展了,直接参考Type的模型设计,得到了DynamicType,然后接下来的操作也TYpe一样。

    目前MethodInfo无法使用DynamicMethod替代,因为存在了范型,无法使用通用的delegate去模拟。。。 

    本来以为,通过DynamicMethod,最少能提高性能10倍吧,可是用在了项目上,却发现没有变化!!!!  

    我在序列化中使用,却发现性能根本没有太大的提升,后来发现反射去Get/Set实际占性能损失很小,另外一大部分在

    1. 集合的操作(List / Dictionary / ...)

    2. Type.GetProperties 等类似的操作。

    3. attribute的获取操作。

    没办法,看来要继续努力,接下来打算把整个Type对象使用Dynamic去托管了。 

  • 相关阅读:
    POJ 3263 Tallest Cow(线段树)
    面试题54——表示数值的字符串
    ORA-01555错误总结(二)
    《AndroidStudio每日一贴》11. 重构之提炼为常量
    机器学习系统构建
    jsp不通过form和Ajax提交
    南邮算法分析与设计实验2 动态规划法
    cocos2d-x 3.2 之 2048 —— 第五篇
    Cocos2d-x学习资源集锦+有奖抽楼活动
    VMware虚拟机无法识别U盘解决方式
  • 原文地址:https://www.cnblogs.com/zc22/p/1749459.html
Copyright © 2011-2022 走看看