类拷贝效率测试

现在做的项目原本是WCF+EF的,原本是把EF的类直接给WCF用的。现在需要分开,以便WCF类和EF类分别独立演化,因为前端和后端的人员不同,类设计习惯不同;而且有时候为了数据库表的设计,EF类无法直接给前端用。先不论这部分的设计思路对不对,在服务接口部分需要WCF类和EF类转换,因为基本是相同的类对象,除了一部分属性不同外,基本上属性是都相同的,就考虑用反射统一转换,当然,后续演化属性名很多不同的话,就会有问题。

总之,我要测试一下用反射动态拷贝和代码写死静态拷贝的效率差别,不用测试肯定也知道反射效率低,只是想看看差别多少。

两个类:

LocationCard,EF类,MVC中在页面上编辑的类

    public class LocationCard:ITag
    {
        /// <summary>
        /// 主键Id
        /// </summary>
        [Display(Name = "主键Id")]
        public int Id { get; set; }

        /// <summary>
        /// 对接Id
        /// </summary>
        [Display(Name = "对接Id")]
        public int? Abutment_Id { get; set; }

        /// <summary>
        /// 终端编号
        /// </summary>
        [Display(Name = "终端编号")]
        [Required]
        public string Code { get; set; }

        /// <summary>
        /// 终端名称
        /// </summary>
        [Display(Name = "终端名称")]
        [Required]
        public string Name { get; set; }

        /// <summary>
        /// 描述
        /// </summary>
        [Display(Name = "描述")]
        public string Describe { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }

Tag WCF类 传输给前端用的类对象

    public class Tag: ITag
    {
        public int Id { get; set; }

        public string Code { get; set; }

        public string Name { get; set; }

        public string Describe { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }

ITag的内容就是Tag中的那些属性

反射方式转换:

public static List<T2> ConvertObjectList<T1, T2>(this IList<T1> list) where T2 : class, new()
        {
            if (list == null) return null;
            Stopwatch stopwatch=new Stopwatch();
            stopwatch.Start();

            Type type1 = typeof(T1);
            Type type2 = typeof(T2);
            
            //PropertyInfo[] propertyInfos1 = type1.GetProperties();
            PropertyInfo[] propertyInfos2 = type2.GetProperties();

            List<T2> listNew = new List<T2>();
            foreach (T1 item in list)
            {
                //T2 itemNew = ConvertObjectTo<T1, T2>(item);
                //listNew.Add(itemNew);

                T2 obj2 = new T2();
                try
                {
                    foreach (PropertyInfo p2 in propertyInfos2)
                    {
                        try
                        {
                            PropertyInfo p1 = type1.GetProperty(p2.Name);
                            if (p1 == null) continue;
                            object value = p1.GetValue(item);
                            p2.SetValue(obj2, value);
                        }
                        catch (Exception ex)
                        {
                            LogEvent.Info(ex.ToString());
                        }

                    }
                    listNew.Add(obj2);
                }
                catch (Exception ex)
                {
                    LogEvent.Info(ex.ToString());
                }
            }
            stopwatch.Stop();
            LogEvent.Info("ConvertObjectList Time:" + stopwatch.Elapsed);
            return listNew;
        }

静态代码方式转换

        #region LocationCard <=> Tag
        public static List<Tag> ToWcfModelList(this List<LocationCard> list1)
        {
            return list1.ToTModel().ToWCFList();
        }

        public static List<Tag> ToTModel(this List<LocationCard> list1)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            List<Tag> list2 = new List<Tag>();
            foreach (var item1 in list1)
            {
                list2.Add(item1.ToModel());
            }

            stopwatch.Stop();
            LogEvent.Info("ToTModel Of List Time:" + stopwatch.Elapsed);
            return list2;
        }

        public static Tag ToModel(this LocationCard item1)
        {
            Tag item2 = new Tag();
            item2.Id = item1.Id;
            item2.Name = item1.Name;
            item2.Code = item1.Code;
            item2.Describe = item1.Describe;
           
            return item2;
        }

        public static List<LocationCard> ToDbModel(this List<Tag> list1)
        {
            //return list1.ConvertObjectList<Tag, LocationCard>();
            var list2 = new List<LocationCard>();
            foreach (var item1 in list1)
            {
                list2.Add(item1.ToDbModel());
            }
            return list2;
        }

        public static LocationCard ToDbModel(this Tag item1)
        {
            LocationCard item2 = new LocationCard();
            item2.Id = item1.Id;
            item2.Name = item1.Name;
            item2.Code = item1.Code;
            item2.Describe = item1.Describe;
            return item2;
        }
        #endregion

测试代码

class Program
    {
        static void Main(string[] args)
        {
            string input = "";

            Console.WriteLine("Input Count:");
            input = Console.ReadLine();
            while (input.ToLower() != "q") 
            {
                int count = int.Parse(input);
                for (int i = 1; i < 10; i++)
                {
                    TestByCount(count*i);
                }

                Console.WriteLine("Input Count:");
                input = Console.ReadLine();
            } 

            Console.WriteLine("Exit");
            Console.Read();
        }

        private static void TestByCount(int count)
        {
            Console.WriteLine("Count:" + count);
            List<LocationCard> cards = InitList(count);
            List<Tag> tags = cards.ConvertObjectList<LocationCard, Tag>();
            List<Tag> tags2 = cards.ToTModel();
            Console.WriteLine();
        }

        private static List<LocationCard> InitList(int count)
        {
            List<LocationCard> cards = new List<LocationCard>();

            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            for (int i = 0; i < count; i++)
            {
                LocationCard card = new LocationCard();
                card.Id = i;
                card.Name = "Card" + i;
                card.Code = "Code" + i;
                card.Abutment_Id = i;
                card.Describe = "Describe" + i;

                //card.Id = i;
                //card.Name = "Card";
                //card.Code = "Code";
                //card.Abutment_Id = i;
                //card.Describe = "Describe";
                cards.Add(card);
            }
            stopwatch.Stop();
            LogEvent.Info("InitList Time:" + stopwatch.Elapsed);
            return cards;
        }
    }

测试结果:

总之100万时反射需要2s多,而静态方法则0.2s则不到,满了13倍左右。

1w以下的小数量,相同属性可以考虑用反射方式,因为不用写代码!

好多类呢,写个工具自动生成转换代码吧。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值