当前位置:  开发笔记 > 编程语言 > 正文

C#中的DataTable.Select和Performance问题

如何解决《C#中的DataTable.Select和Performance问题》经验,为你挑选了1个好方法。



1> Oguz Ozgul..:

.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]);
}

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有