任意两个对象赋值,用Spring.Objects.ObjectWrapper效率比直接反射还慢?

 任意两个对象,对他们存在相同的字段赋值,字段包括普通property,其他类对象,父类的property。由于是任意对象,不知道类型

,因此一般的做法是直接调用反射,spring.net内部封装了任意对象赋值的方法,但是经过我的测试,发现它的速度比直接反射还慢,不知

道是自己哪里没有优化,还是方法执行有问题,粗略看了一下spring.net内部源代码,发现它自己实现了表达式树和AST来解析它的包装对象,

没太看明白,如果有谁之前研究过,可以分享一些技术文章出来。

本次用直接反射,Spring.net的ObjectWrapper和jeffreyzhao的FastReflectionLib http://www.codeplex.com/FastReflectionLib进行赋值的

效率比较。

直接反射代码如下:

直接反射代码
         ///   <summary>
        
///  把原始对象的值赋值给目标对象
        
///   </summary>
        
///   <param name="originObj"> 原始对象 </param>
        
///   <param name="targetObj"> 目标对象 </param>
         public   static   void  Fill( object  originObj,  object  targetObj)
        {
            PropertyInfo[] properties 
=  originObj.GetType().GetProperties();

            
foreach  (PropertyInfo item  in  properties)
            {
                PropertyInfo property 
=  targetObj.GetType().GetProperty(item.Name);
                
try
                {
                    property.SetValue(targetObj, item.GetValue(originObj, 
null ),  null );
                }
                
catch
                {
                    
continue ;
                }
            }
        }

 

Spring.net用ObjectWrapper实现赋值代码如下:

Spring.net
         ///   <summary>
        
///  把原始对象的值赋值给目标对象
        
///   </summary>
        
///   <param name="originObj"> 原始对象 </param>
        
///   <param name="targetObj"> 目标对象 </param>
         public   static   void  Fill < O,T > ( object  originObj,  object  targetObj)
        {
            ObjectWrapper ow 
=   new  ObjectWrapper(originObj);
            ObjectWrapper tw 
=   new  ObjectWrapper(targetObj);
            PropertyInfo[] properties 
=  ow.GetPropertyInfos();

            
foreach  (PropertyInfo item  in  properties)
            {
                
try
                {
                    tw.SetPropertyValue(item.Name, ow.GetPropertyValue(item.Name));
                }
                
catch
                {
                    
continue ;
                }
            }
        }

 

用FastReflectionLib实现赋值代码如下:

FastReflectionLib
         ///   <summary>
        
///  把原始对象的值赋值给目标对象
        
///   </summary>
        
///   <param name="originObj"></param>
        
///   <param name="targetObj"></param>
         public   static   void  Fill( object  originObj,  object  targetObj)
        {
            PropertyInfo[] properties 
=  originObj.GetType().GetProperties();

            
foreach  (PropertyInfo item  in  properties)
            {
                PropertyInfo property 
=  targetObj.GetType().GetProperty(item.Name);
                
try
                {
                    property.FastSetValue(targetObj, item.FastGetValue(originObj));
                }
                
catch
                {
                    
continue ;
                }
            }
        }

 

为了让任意对象更加真实性,我的两个对象将继承一个类,并且对象中还包括其他对象,对象具体内容就不展现出来了,最下面提供源代

码下载,感兴趣的可以下载试试,如果有什么好的建议,不忘了告诉我一下。

测试代码如下: 

测试代码
         static   void  Main( string [] args)
        {
            var origin 
=   new  SourceObject() { Id  =   2 , Name  =   " lawson " , Url  =   " http://lawson.cnblogs.com " , CreateTime  =   new  DateTime( 2000 10 10 ), baseStr  =   " 1base " , otherO  =   new  OtherObj() { others = " other object others " } };
            var target 
=   new  TargetObject() { Id  =   3 , Name  =   " aa " , Url  =   " http://www.cnblogs.com " , CreateTime  =   new  DateTime( 2010 10 1 ) };

            
int  time  =   10000 ;


            Stopwatch stopwatch4 
=  Stopwatch.StartNew();
            
for  ( int  i  =   0 ; i  <  time; i ++ )
            {
                target.Id 
=  origin.Id;
                target.Name 
=  origin.Name;
                target.Url 
=  origin.Url;
                target.CreateTime 
=  origin.CreateTime;
            }
            Console.WriteLine(
string .Format( " 直接赋值耗时:{0} 毫秒 " , stopwatch4.ElapsedMilliseconds));


            Stopwatch stopwatch2 
=  Stopwatch.StartNew();
            
for  ( int  i  =   0 ; i  <  time; i ++ )
            {
                DirectReflect.Exchanger.Fill(origin, target);
            }
            Console.WriteLine(
string .Format( " 直接反射赋值耗时:{0} 毫秒 " , stopwatch2.ElapsedMilliseconds));

            Stopwatch stopwatch 
=  Stopwatch.StartNew();
            
for  ( int  i  =   0 ; i  <  time; i ++ )
            {
                SpringNet.Exchanger.Fill
< SourceObject, TargetObject > (origin, target);
            }
            Console.WriteLine(
string .Format( " Springnet赋值耗时:{0} 毫秒 " , stopwatch.ElapsedMilliseconds));
                        
            Stopwatch stopwatch3 
=  Stopwatch.StartNew();
            
for  ( int  i  =   0 ; i  <  time; i ++ )
            {
                FastReflect.Exchanger.Fill(origin, target);
            }
            Console.WriteLine(
string .Format( " FastReflect赋值耗时:{0} 毫秒 " , stopwatch3.ElapsedMilliseconds));

            Console.ReadKey();

        }

 

 

在Release编译运行下的结果如下:

直接赋值耗时:0 毫秒
直接反射赋值耗时:187 毫秒
Springnet赋值耗时:3642 毫秒
FastReflect赋值耗时:133 毫秒

在我的测试中,Springnet的ObjectWrapper和直接反射或者FastReflect比较中,性能完全不是一个数量级的。

下面提供我的测试代码下载

 /Files/Lawson/ExchangeValue-lawson.rar

你可能感兴趣的:(spring)