Словарь C # содержит ключ против ключей.Any () - PullRequest
0 голосов
/ 27 августа 2018

Вот моя ситуация:

Я использую объект словаря для хранения некоторых ключей, а затем, основываясь на том, что ключ существует в объекте, код выполняет какое-то действие.

До сих пор я использовал - LINQ - Any() dictionaryObject.Any(x => x.Key.Equals("SomeParameter")). Это работало и удовлетворяло все сценарии, пока мой объект словаря внезапно не получил 200 000 ключей.

Это начало влиять на производительность, как и остальная часть процесса.

Тогда я понимаю, что есть словарный метод ContainsKey("SomeParameter"), и после его использования производительность действительно улучшилась.

Теперь мне больше интересно узнать, чем ContainsKey отличается от LINQ Any, поскольку я подчеркнул, что код использует for & foreach соответственно, что означает, что он проходит по списку.

1 Ответ

0 голосов
/ 27 августа 2018

Это код для метода 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;
    }

Как видите, когда у вас есть ключ,

  • вы получите хеш-код для него
  • корзина доступа для получения индекса
  • доступ к данным с этим индексом

Это O (1) операций, в то время как Any является частью IEnumerable и выполняет простые итерации по последовательности элементов, пока не будет выполнено условие, следовательно, O (n) - гораздо менее масштабируемое. И это то, что вы наблюдаете - с ростом объема данных производительность ухудшается для Any.

См. Объявление Dictionary из System.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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...