キーが十分に分散されたハッシュを持っている限り、TryGetValue と ContainsKey はそのサイズでかなり高速になるはずです。
ディクショナリには、インデックス可能な数の「バケット」があります。キーで値を追加または検索すると、GetHashCode() によって返された値が取得され、バケットの数よりも小さくなるように再度ハッシュ化されます (通常、モジュロのような単純なものですが、実装は定義されていません)。関連するバケットを調べます。
バケットには現在、0 個以上のアイテムがあります。ディクショナリは、.Equals() を使用して各項目をキーと比較します。
適切なバケットを見つける最初のビットは、一定時間 O(1) になります。キーをバケット内のキーと比較する 2 番目のビットは線形時間 O(n) になります。ここで、n はコレクション全体ではなく、そのバケット内のアイテムの数のみに関連します。
一般に、各バケット内の項目は非常に少ないはずです (これを維持しようとするためにバケットの数が増加します) ため、操作は基本的に一定の時間です。
ただし、ハッシュ コードの実装が不十分な場合、同じバケットに多数のキーが存在することになります。毎回 0 を返すだけの故意に悪い GetHashCode を持つオブジェクトを実験することでわかるように、時間の計算量は O(n) にどんどん近づいていきます。リストも O(n) であるため、最悪の場合はリストよりも悪いですが、ディクショナリにはより多くのオーバーヘッドがあります。
これは、心配する必要があるということですか?いいえ、比較的ナイーブなハッシュ方法でも比較的良い結果が得られるはずです。文字列キーを使用している場合は、おそらくすでに十分すぎるほどです。単純な組み込み型を使用している場合はなおさらです。
ただし、辞書へのアクセスが遅いことがわかった場合は、これに注意して、GetHashCode() メソッドを修正するか、IEqualityComparer を作成してください (GetHashCode() および Equals() で使用するための外部ルールを定義できます)。辞書、ハッシュセットなど)。
ほとんどの場合、3000 は何もありませんが、問題ありません。