当前位置:编程学习 > C#/ASP.NET >>

颠覆常识??Reflection、Delegate、Expression 生成实体类,实测结果,反射最快。

我的ORM一直是用反射来实现动态生成Entity的,最近想提高一下效率,就尝试了一下用其他的方法来生成实体类。平时看到的资料都说用Expression的速度已经接近于Emit了,效率非常高,但测试的结果却让我大跌眼镜。。。下面对直接赋值、反射、委托、Expression四种方式来生成实体类进行测试。(暂时不考虑Emit),如果大家有其他更好的方法来生成实体类,请不吝赐教,谢谢。
先上测试结果:(环境:Windows 7 64 bit, I7 950,12G ram, VS2010)
Assign       ,generate entity 10000 times, time: 2
Reflection   ,generate entity 10000 times, time: 54
Delegate     ,generate entity 10000 times, time: 134
Expression   ,generate entity 10000 times, time: 4323

Press any key to continue...

从结果中可以,直接赋值最快(但写和维护太麻烦,实际项目中一般不考虑),然后就是反射,到了用Expression的方式,效率是数量级的下降啊,比反射慢几十倍?
不知道是不是我的测试用例写的问题,下面详细说明一下我的测试过程:
1、原始数据是一个DataTable, 只有一行数据,三列。分别为Name,Age,Sex ,下面所有的转化只是把DataTable的第一行转为一个实体类。
public static DataTable GetCustomer()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add(new DataColumn("Name", typeof(System.String)));
            dt.Columns.Add(new DataColumn("Age", typeof(System.String)));
            dt.Columns.Add(new DataColumn("Sex", typeof(System.String)));

            DataRow dr = dt.NewRow();
            dr["Name"] = "Andy";
            dr["Age"] = "33";
            dr["Sex"] = "Male";

            dt.Rows.Add(dr);
            return dt;

        }

2、要生成的实体类也很简单,只有三个property,为了避免类型转换等问题,用最简单的,都是string 类型。
public class Customer
    {
        public string Name { get; set; }
        public string Age { get; set; }
        public string Sex { get; set; }
    }


3、直接赋值的方法:
 1 public class ToEntityByAssign
 2     {
 3        public Customer GetEntity(DataTable dt)
 4        {
 5            DataRow dr = dt.Rows[0];
 6            Customer cus = new Customer();
 7            cus.Name = dr["Name"].ToString();
 8            cus.Age = dr["Age"].ToString();
 9            cus.Sex = dr["Sex"].ToString();
10            return cus;
11        }
12     }

4、反射生成实体类的方法:
 1  public class ToEntityByReflection<T>
 2     {
 3         public T GetEntity(DataTable dt)
 4         {
 5             Type type = typeof(T);
 6             T model = (T)Activator.CreateInstance(typeof(T));
 7             DataRow dr = dt.Rows[0];
 8
 9             foreach (PropertyInfo pi in type.GetProperties())
10             {
11                 pi.SetValue(model,Convert.ChangeType(dr[pi.Name],pi.PropertyType), null);
12             }
13            
14             return model;
15         }
16     }

5、Delegate 生成实体类的方法:
 1 public delegate void SetString(string value);
 2     public class ToEntityByDelegate<T>
 3     {
 4         public T GetEntity(DataTable dt)
 5         {
 6             Type type = typeof(T);
 7             T model = (T)Activator.CreateInstance(typeof(T));
 8             DataRow dr = dt.Rows[0];
 9
10             foreach (DataColumn dc in dt.Columns)
11             {
12                 var setDelegateString = CreateStringDelegate(model, dc.ColumnName);
13                 setDelegateString(dr[dc.ColumnName].ToString());
14             }
15             return model;
16         }
17
18         private static SetString CreateStringDelegate(object obj, string PropertyName)
19         {
20             MethodInfo mi = obj.GetType().GetProperty(PropertyName).GetSetMethod();
21             Type type = typeof(SetString);
22             return (SetString)Delegate.CreateDelegate(type, obj, mi);
23         }
24     }

6、Expression 生成实体的方法:
public static class ToEntityByExpression
    {
        public static T GetEntity<T>(DataTable dt)
        {
            T t = (T)Activator.CreateInstance(typeof(T));
            DataRow dr = dt.Rows[0];
 &nb

补充:软件开发 , C# ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,