字典的快速迭代(字符串,列表>

时间:2015-05-26 17:49:02

标签: c# .net

我有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秒)。如何更快地查询记录?

3 个答案:

答案 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查找 你仍在迭代词典,但现在你有一个非常有效的比较 这里的好处是你只需要迭代字典一次 先试试这个。