颠覆常识??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# ,