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