【问题标题】:C# Dictionary ContainsKey Vs Keys.Any()C# Dictionary ContainsKey 与 Keys.Any()
【发布时间】:2018-08-27 17:16:22
【问题描述】:

这是我的情况:

我正在使用字典对象来存储一些键,然后基于对象中存在的键,代码正在执行一些动作。

到目前为止,我一直在使用 - LINQ - Any() dictionaryObject.Any(x => x.Key.Equals("SomeParameter"))。在我的字典对象突然获得 200,000 个键之前,这是可行的,并且可以满足所有场景。

它开始影响性能,其他过程也是如此。

然后我意识到,有一个字典方法ContainsKey("SomeParameter"),使用后,性能确实提高了。

现在我更感兴趣的是 ContainsKey 与 LINQ Any 的不同之处,因为我下划线的代码分别使用 forforeach,这意味着它循环遍历列表。

【问题讨论】:

  • ContainsKey 将使用密钥的哈希值来查看字典是否包含它。这是 O(1)。 Any() 不使用字典查找,并且是 O(n)。
  • 当您对框架方法的内部结构感到好奇时,您可以使用.NET framework reference source,或者阅读.NET API Browser 上特定框架类的文档,这解释了为什么Dictionary 查找@987654323 @。您还可以看到Any 是如何实现的以及它处理的特殊情况。

标签: c# linq dictionary


【解决方案1】:

这是 ContainsKey 方法的代码

  private int FindEntry(TKey key)
    {
      if ((object) key == null)
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
      if (this.buckets != null)
      {
        int num = this.comparer.GetHashCode(key) & int.MaxValue;
        for (int index = this.buckets[num % this.buckets.Length]; index >= 0; index = this.entries[index].next)
        {
          if (this.entries[index].hashCode == num && this.comparer.Equals(this.entries[index].key, key))
            return index;
        }
      }
      return -1;
    }

如你所见,一旦你有了钥匙,

  • 你会得到它的哈希码
  • 访问bucket获取索引
  • 使用该索引访问数据

这是 O(1) 操作,而 AnyIEnumerable 的一部分,并且对一系列元素执行简单的迭代,直到满足条件,因此 O(n) - 可扩展性要小得多。这就是您所观察到的 - 随着数据量的增长,Any 的性能变得更差。

参见 System.Collections.Generic、mscorlib 中的 Dictionary 声明

   public class Dictionary<TKey, TValue> : IDictionary<TKey, TValue>, 
                    ICollection<KeyValuePair<TKey, TValue>>, 
                    IEnumerable<KeyValuePair<TKey, TValue>>,  //this one "brings" Any
                    IEnumerable, 
                    IDictionary, 
                    ICollection, 
                    IReadOnlyDictionary<TKey, TValue>, 
                    IReadOnlyCollection<KeyValuePair<TKey, TValue>>, 
                    ISerializable, 
                    IDeserializationCallback

【讨论】:

猜你喜欢
  • 2016-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多