我有150万条记录的清单。我需要迭代这个List大约300次来拉出某些记录来执行计算。我假设将我的List转换为Dictionary会在迭代期间使我的查找更快。
我的列表由以下类组成:
class SummaryRecord
{
public int CalcData { get; set; }
public string Id2 { get; set; }
public string Id2 { get; set; }
}
由于我有两个ID使记录唯一,我将我的列表转换为这样的字典:
Dictionary<string, SummaryRecord> dictSummaries = summaries.ToDictionary(
e => e.Id1 + "+" + e.Id2 + "+" + e.CalcData);
然后我循环遍历300个ID对的辅助列表,从大清单中提取记录。
foreach(var ids in listOfIds)
{
var filteredData = from d in dictSummaries
where
d.Key.Contains(ids.Id1 + "+" + ids.Id2)
select d;
//perform operation on filteredData here. This code is slow as well.
filteredData.Count()
}
基于我所看到的性能,这显然不是非常有效,因为执行每次迭代需要大约1秒(300秒)。如何更快地查询记录?
答案 0 :(得分:3)
原样,你实际上并没有使用字典的强大功能。您的查询将迭代字典中的每个记录,检查您给出的条件。
由于您拥有完整密钥,因此您应该直接查找每个密钥:
string key = ids.Id1 + "+" + ids.Id2;
SummaryRecord summaryRecord = dictSummaries[key];
如果您不确定该密钥是否存在,请务必执行TryGetValue()或进行ContainsKey()检查。
答案 1 :(得分:1)
由于您使用3个字段作为字典的键
summaries.ToDictionary( e =&gt; e.Id1 +&#34; +&#34; + e.Id2 +&#34; +&#34; + e.CalcData);
我相信有可能有倍数,id1 + id2。 如果是这种情况,你可以使用ToLookup而不是ToDictionary。
var lookup = summaries.ToLookup(e => e.Id1 + "+" + e.Id2);
然后
foreach(var ids in listOfIds)
{
var filteredData = lookup[ids.Id1 + "+" + ids.Id2];
//perform operation on filteredData here. This code is slow as well.
filteredData.Count()
}
现在如果不能有多个id1 + id2,你为什么要连接id1 + id2 + CalcData ?
答案 2 :(得分:-1)
很确定你接到String.Contains的电话
您正在迭代字典中的EACH键并测试该键包含另一个字符串
所以&#34; prekey1key2&#34;包含&#34; key1key2。
如果你打算得到一个确切的查找,请注意不是你得到的(并且你根本没有使用Dictionary HashBuckets)。
您正在迭代每条记录。您根本没有使用字典查找。 更糟糕的是,您正在listOfIds中的每一行迭代Dictionary中的每条记录。
如果ID1和ID2形成一个唯一的密钥,那么将其用作密钥并直接查找,如Kevin所给出的答案 这是哈希查找并且禁止吸烟
SummaryRecord summaryRecord = dictSummaries[key];
同样选择好散列的ID1,ID2 你可以使用两个可以组合成Int32的int16吗? 您可以使用真实密钥覆盖GetHashCode 并覆盖Equals。
另一种方法
class SummaryRecord
{
public int CalcData { get; set; }
public string Key { get { return Id1 + Id2; }
public string Id2 { get; set; }
public string Id2 { get; set; }
}
private HashSet<String> keyToFind = new HashSet<String>() {"key1","key2"};
var filteredData = from d in dictSummaries.where(x => keyToFind.Contains(x.key));
包含将是HashBucket查找 你仍在迭代词典,但现在你有一个非常有效的比较 这里的好处是你只需要迭代字典一次 先试试这个。