.Net 4.5和问题仍然存在.
以下是一个简单基准测试的结果,其中DataTable.Select和不同的字典实现比较CPU时间(结果以毫秒为单位)
#Rows Table.Select Hashtable[] SortedList[] Dictionary[] 1000 43,31 0,01 0,06 0,00 6000 291,73 0,07 0,13 0,01 11000 604,79 0,04 0,16 0,02 16000 914,04 0,05 0,19 0,02 21000 1279,67 0,05 0,19 0,02 26000 1501,90 0,05 0,17 0,02 31000 1738,31 0,07 0,20 0,03
问题:
DataTable.Select方法在内部创建"System.Data.Select"类实例,此"Select"类根据查询中指定的字段(列)创建索引.Select类重新使用它创建的索引,但DataTable实现不会重用Select类实例,因此每次调用DataTable.Select时都会重新创建索引.(通过反编译System.Data可以观察到此行为)
解:
假设以下查询
DataRow[] rows = data.Select("COL1 = 'VAL1' AND (COL2 = 'VAL2' OR COL2 IS NULL)");
而是使用与用作过滤器的列的值的不同值组合对应的键创建和填充字典.(这个相对昂贵的操作必须只进行一次,然后必须重新使用字典实例)
Dictionary> di = new Dictionary >(); foreach (DataRow dr in data.Rows) { string key = (dr["COL1"] == DBNull.Value ? " " : dr["COL1"]) + "//" + (dr["COL2"] == DBNull.Value ? " " : dr["COL2"]); if (di.ContainsKey(key)) { di[key].Add(dr); } else { di.Add(key, new List ()); di[key].Add(dr); } }
查询字典(可能需要多个查询)来过滤行并将结果合并到List中
string key1 = "VAL1//VAL2"; string key2 = "VAL1//"; List () results = new List (); if (di.ContainsKey(key1)) { results.AddRange(di[key1]); } if (di.ContainsKey(key2)) { results.AddRange(di[key2]); }