字典/ Hashset构建优化

时间:2013-12-11 16:56:47

标签: c# optimization dictionary lookup hashset

如果钥匙已经存在,是否有任何方法检查?

假设

  • 在迭代列表
  • 之前,我们不知道所有可能的键
  • 新方法应该更快地运作

    var list = new List<Person>(); // { int Id; int DepartmentId; string Name; }
    ... // let's imagine that list is getting filled
    
    var dict = new Dictionary<int, List<Person>>();
    
    foreach (var p in list)
    {
       if(!dict.ContainsKey(p.DepartmentId))
            dict.Add(p.DepartmentId, new List<int>());
    
       dict[p.DepartmentId].Add(p);
    }
    

1 个答案:

答案 0 :(得分:2)

我可以看到两个改进,但是每个改进本身仍然会检查密钥存在。

第一个减少了对字典的访问次数。从理论上讲,这可能会更快,但计算复杂性仍然相同,实际上差异可能是微不足道的:

1)

var dict = new Dictionary<int, List<Person>>();

foreach (var p in list)
{
    List<Person> value = null;

    if(!dict.TryGetValue(p.DepartmentId, out value))
    {
        value = new List<int>();
        dict.Add(p.DepartmentId, value);
    }

    value.Add(p);
}

第二次改进增加了一些语法糖:

2)

public static class DictionaryExtensions
{
    public static TValue GetOrAdd<TKey, TValue>(
        this IDictionary<TKey, TValue> dictionary,
        TKey key) where TValue : new()
    {
        TValue value;
        if (!dictionary.TryGetValue(key, out value))
        {
            value = new TValue();
            dictionary.Add(key, value);
        }

        return value;
    }
}

然后:

foreach (var p in list)
{
    dict
        .GetOrAdd(p.DepartmentId)
        .Add(p.DepartmentId);
}

正如Servy所指出的,您可能希望为GetOrAdd扩展添加参数,以便更好地控制默认值的创建。