文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>任意两个对象赋值,用Spring.Objects.ObjectWrapper效率比直接反射还慢?

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

时间:2010-12-25  来源:Lawson

,因此一般的做法是直接调用反射,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

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载