使用DynamicMethod替代反射,提高100倍的性能!(附源码)

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

前言

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

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

 

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

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

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

 

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

代码测试结果 

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

测试对象:

ExpandedBlockStart.gif 代码
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 动态编译

ExpandedBlockStart.gif 代码
         // 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 " );
        }

 

测试结果:

ExpandedBlockStart.gif 代码
------  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动态编译

ExpandedBlockStart.gif 代码
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 " );
        }

 

测试结果

ExpandedBlockStart.gif 代码
------  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动态编译

ExpandedBlockStart.gif 代码
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 " );
        }

 

测试结果 

ExpandedBlockStart.gif 代码
------  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动态编译

ExpandedBlockStart.gif 代码
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 " );
        }

 

 测试结果 

ExpandedBlockStart.gif 代码
------  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动态编译 

ExpandedBlockStart.gif 代码
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 " );
        } 

测试结果 

ExpandedBlockStart.gif 代码
------  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动态编译

ExpandedBlockStart.gif 代码
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 "" 0 0 "" 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 "" 0 0 "" , ( 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 "" 0 0 "" , ( double ) 0  });
            }

            EndTest(
" end dynamic " );
        }

 

测试结果 

ExpandedBlockStart.gif 代码
------  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去托管了。 

转载于:https://www.cnblogs.com/zc22/archive/2010/06/01/1749459.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值