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