C#Dictionary ContainsKey Vs Keys.Any()

Avi*_*ale 0 c# linq dictionary

这是我的情况:

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

直到现在我正在使用 - LINQ - Any() dictionaryObject.Any(x => x.Key.Equals("SomeParameter")).这是工作将满足所有情况,直到我的字典对象突然得到200,000键.

它开始影响性能,其余的过程也是如此.

然后我意识到,有一种字典方法ContainsKey("SomeParameter"),在使用它之后,性能确实得到了提升.

现在我更感兴趣的是看看ContainsKey与LINQ有什么不同,Any因为我强调代码分别使用for&foreach,这意味着它通过列表循环.

Tig*_*ran 7

这是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;
    }
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,一旦有了钥匙,

  • 你得到它的哈希码
  • 访问存储桶以获取索引
  • 使用该索引访问数据

它是O(1)运算,同时Any是一部分IEnumerable元素的一部分,并且对元素序列执行简单迭代,直到满足条件,因此O(n) - 更不易于扩展.这就是你所观察到的 - 随着数据量的增长,性能变得更糟Any.

请参阅DictionarySystem.Collections.Generic,mscorlib的声明

   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
Run Code Online (Sandbox Code Playgroud)