C#浅谈类实体与DataTable执行效率


问题根源:现在编码已经习惯了面向对象编码,数据库访问层也由ORM代替了ADO,DataTable一般用的越来越少,可是一些公用方法还是用到DataTable了,理由其实很简单就是公用方法里不用DataTable就得用反射访问实体集合,反射的访问效率比DataTable低很多是毋庸置疑的。可是我还是觉得很苦恼,心中有两个疑问:

1、访问实体集合到底比访问DataTable慢多少呢?

2、后台数据层提供的是实体集合,调用公用方法势必要转为DataTable,那转换耗时多少呢?

 

接下来我新建了一个控制台程序,简单写了一个实体对象:

 1 public class TestEntity
 2     {
 3         public string Col1 { get; set; }
 4         public string Col2 { get; set; }
 5         public string Col3 { get; set; }
 6         public string Col4 { get; set; }
 7         public string Col5 { get; set; }
 8         public string Col6 { get; set; }
 9         public string Col7 { get; set; }
10         public string Col8 { get; set; }
11         public string Col9 { get; set; }
12         public string Col10 { get; set; }
13         public string Col11 { get; set; }
14         public string Col12 { get; set; }
15         public string Col13 { get; set; }
16         public string Col14 { get; set; }
17         public string Col15 { get; set; }
18         public string Col16 { get; set; }
19         public string Col17 { get; set; }
20         public string Col18 { get; set; }
21         public string Col19 { get; set; }
22         public string Col20 { get; set; }
23         public string Col21 { get; set; }
24         public string Col22 { get; set; }
25         public string Col23 { get; set; }
26         public string Col24 { get; set; }
27         public string Col25 { get; set; }
28         public string Col26 { get; set; }
29         public string Col27 { get; set; }
30         public string Col28 { get; set; }
31         public string Col29 { get; set; }
32         public string Col30 { get; set; }
33     }
public class TestEntity

然后写了一个创建实体集合的方法:

 1 private static IList<TestEntity> CreateList(long count)
 2         {
 3             var result = new List<TestEntity>();
 4 
 5             for (var i = 0; i < count; i++)
 6             {
 7                 var entity = new TestEntity();
 8                 var propertys = typeof(TestEntity).GetProperties();
 9                 foreach (var p in propertys)
10                 {
11                     p.SetValue(entity, i.ToString());
12                 }
13                 result.Add(entity);
14             }
15 
16             return result;
17         }
private static IList CreateList(long count)

然后写了一个创建DataTable的方法:

 1 private static DataTable CreateTable(long count)
 2         {
 3             var result = new DataTable();
 4 
 5             for (var i = 1; i <= 30; i++)
 6             {
 7                 result.Columns.Add(new DataColumn("Col" + i.ToString(), Type.GetType("System.String")));
 8             }
 9 
10             for (var i = 0; i < count; i++)
11             {
12                 var row = result.NewRow();
13                 for (var j = 1; j <= 30; j++)
14                 {
15                     row["Col" + j.ToString()] = i;
16                 }
17                 result.Rows.Add(row);
18             }
19 
20             return result;
21         }
private static DataTable CreateTable(long count)

准备工作做好了,现在写了两个读取的方法:

 1 private static void ReadEntity<T>(IList<T> list)
 2         {
 3             for (var i = 0; i < list.Count; i++)
 4             {
 5                 var entity = list[i];
 6                 var propertys = typeof(T).GetProperties();
 7                 for (var j = 0; j < propertys.Count(); j++)
 8                 {
 9                     var value = "";
10                     value += propertys[j].GetValue(entity).ToString();
11                 }
12             }
13         }
private static void ReadEntity(IList list)
 1 private static void ReadDataTable(DataTable data)
 2         {
 3             for (var i = 0; i < data.Rows.Count; i++)
 4             {
 5                 for (var j = 0; j < data.Columns.Count; j++)
 6                 {
 7                     var value = "";
 8                     value += data.Rows[i][j].ToString();
 9                 }
10             }
11         }
private static void ReadDataTable(DataTable data)

记录一下耗时,通过控制台打印出来:

 1 static void Main(string[] args)
 2         {
 3             for (var i = 0; i < 10; i++)
 4             {
 5                 var count = Convert.ToInt64(Console.ReadLine());
 6                 if (count == 0) break;
 7 
 8                 var list = CreateList(count);
 9 
10 
11                 DateTime start = DateTime.Now;
12                 var table = CreateTable(count);
13                 DateTime end = DateTime.Now;
14 
15                 var tick0 = (end - start).Ticks;
16 
17                 start = DateTime.Now;
18                 ReadDataTable(table);
19                 end = DateTime.Now;
20 
21                 var tick1 = (end - start).Ticks;
22 
23                 start = DateTime.Now;
24                 ReadEntity(list);
25                 end = DateTime.Now;
26 
27                 var tick2 = (end - start).Ticks;
28 
29                 Console.WriteLine("DataTable:条数" + count + "耗时" + tick1.ToString());
30                 Console.WriteLine("反射读取Entity:条数" + count + "耗时" + tick2.ToString());
31             }
32         }
static void Main(string[] args)

运行程序,输入行数,显示结果如下:

可以看出反射读取耗时与DataTable读取耗时相比2到4倍。

这时你肯定会想差这么多,看来公用方法使用DataTable是没错了。

但是,开头咱们提到的两个疑问,第一个疑问解决了,但是第二个疑问呢,转换耗时多少呢?

现在我把第二个疑问拆解了一下,转换需要进行的是,创建DataTable,遍历读取实体集合(注意一下这个不是反射),这样我就写了一个方法:

 1 private static DataTable CreateTable(IList<TestEntity> list)
 2         {
 3             var result = new DataTable();
 4 
 5             for (var i = 1; i <= 30; i++)
 6             {
 7                 result.Columns.Add(new DataColumn("Col" + i.ToString(), Type.GetType("System.String")));
 8             }
 9 
10             for (var i = 0; i < list.Count; i++)
11             {
12                 var row = result.NewRow();
13                 row["Col1"] = list[i].Col1;
14                 row["Col2"] = list[i].Col2;
15                 row["Col3"] = list[i].Col3;
16                 row["Col4"] = list[i].Col4;
17                 row["Col5"] = list[i].Col5;
18                 row["Col6"] = list[i].Col6;
19                 row["Col7"] = list[i].Col7;
20                 row["Col8"] = list[i].Col8;
21                 row["Col9"] = list[i].Col9;
22                 row["Col10"] = list[i].Col10;
23                 row["Col11"] = list[i].Col11;
24                 row["Col12"] = list[i].Col12;
25                 row["Col13"] = list[i].Col13;
26                 row["Col14"] = list[i].Col14;
27                 row["Col15"] = list[i].Col15;
28                 row["Col16"] = list[i].Col16;
29                 row["Col17"] = list[i].Col17;
30                 row["Col18"] = list[i].Col18;
31                 row["Col19"] = list[i].Col19;
32                 row["Col20"] = list[i].Col20;
33                 row["Col21"] = list[i].Col21;
34                 row["Col22"] = list[i].Col22;
35                 row["Col23"] = list[i].Col23;
36                 row["Col24"] = list[i].Col24;
37                 row["Col25"] = list[i].Col25;
38                 row["Col26"] = list[i].Col26;
39                 row["Col27"] = list[i].Col27;
40                 row["Col28"] = list[i].Col28;
41                 row["Col29"] = list[i].Col29;
42                 row["Col30"] = list[i].Col30;
43                 result.Rows.Add(row);
44             }
45 
46             return result;
47         }
private static DataTable CreateTable(IList list)

在主函数增加时间记录:

1 start = DateTime.Now;
2                 CreateTable(list);
3                 end = DateTime.Now;
4 
5                 var tick3 = (end - start).Ticks;
6                 Console.WriteLine("Entity:条数" + count + "耗时" + tick3.ToString());
Main

执行结果如下:

创建DataTable加上读取与通过反射直接读取实体集合,耗时相差不是很明显了,起码不是倍率级的了,在大环境下,我个人觉得考虑到维护性和开发效率,我推荐直接使用反射写公用方法。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM