【发布时间】:2016-02-15 05:38:57
【问题描述】:
在我正在编写的应用程序中,我需要将两组潜在的大型数据相互映射。一个是从 Web 服务返回的 List,一个是 DataTable。我需要为列表中的每个项目获取 ANSI(或 ISO)编号,并找到包含该 ANSI 编号的 DataTable 行,然后对其进行处理。
由于 DataTable.Select 非常慢,我必须对 List 中的每个项目都这样做,所以我尝试了更快的替代方案。请记住,DataTable 对象没有数据库。所以我不能利用任何 SQL 功能或类似的东西。
我认为最快的方法可能是使用 KeyValuePair(A:Ansi 编号或 I:Iso 编号)创建字典并将其用作键。该值将是该行的其余部分。创建该字典显然需要一点处理时间,但随后我可以利用字典极快的搜索时间来查找我需要的每一行,然后将这些行添加回表中。因此,在 foreach 循环中,我只会使用字典而不是 O(n) 或 DataTable.Select 具有的 O(1) 复杂度。
令我惊讶的是,字典的速度非常慢。我不知道为什么,直到我发现使用字符串(只是 ANSI 数字)而不是 KeyValuePair 可以显着提高性能。我说话的速度快了几百倍。这怎么可能?这是我的测试方法:
我生成了一个模拟 Web 服务输出的列表。我基于该列表创建一个字典,其中包含一个键(字符串或 KeyValuePair)和 DataRow 作为值。我遍历该列表的 foreach 循环,并在我的字典中搜索该列表中的每个项目,然后为返回的 DataRow 分配一个值。就是这样。
如果我使用 KeyValuePair 作为访问字典的键,则访问 1,000 个项目需要几秒钟,如果我修改字典以仅将字符串作为键,则访问 10,000 个项目需要几毫秒。仅供参考:我设计了测试,以便总是有命中,所以总能找到所有键。
这是我正在测量时间的代码块:
foreach(ProductList.Products item in pList.Output.Products)
{
//KeyValuePair<string, string> kv = new KeyValuePair<string, string>("A", item.Ansi);
DataRow row = dict[item.Ansi];
for (int i = 0; i < 10; i++)
{
row["Material"] = item.Material + "a"; //Do stuff just for debugging
}
hits++;
}
那么,如果我使用 Dictionary(KeyValuePair,DataRow) 而不是 Dictionary(String,DataRow),执行时间怎么可能突然变长数百倍?
【问题讨论】:
-
SO 上的人过去不那么挑剔。我敢打赌,对这个问题投反对票的人在按下不赞成按钮之前没有阅读过它。见鬼的人,看在上帝的份上,不要再这样做了……
-
不同的问题,但相同的答案,请看stackoverflow.com/a/251619/18797
标签: c# .net dictionary