.NET HashTableとディクショナリ-ディクショナリを同じくらい高速にできますか?


276

辞書またはハッシュテーブルをいつ、なぜ使用するのかを理解しようとしています。私はここで少し検索を行ったところ、私が完全に同意するディクショナリの一般的な利点について話している人を見つけました。

しかし、私はまた、ディクショナリを読んだところ、オブジェクトが挿入された順序で返されるとは限りません。HashTableが行う場所。私が理解しているように、これによりHashTableが状況によってははるかに高速になる。

私の質問は本当に、それらの状況は何でしょうか?上記の仮定が間違っていますか?どちらを選択するのにどのような状況を使用できますか(はい、最後の1つは少しあいまいです)。


5
私はこれに賛成したくないのですが、あなたのカルマは7,777であり、私はあなたのためにそれを台無しにする男になりたくありません。
CaptainMarvel 2018年

回答:


298

System.Collections.Generic.Dictionary<TKey, TValue>System.Collections.Hashtableクラスはどちらもハッシュテーブルのデータ構造を内部的に維持しています。それらのいずれも、アイテムの順序の保持を保証しません。

ボクシング/アンボクシングの問題は別として、ほとんどの場合、非常に類似したパフォーマンスが得られます。

それらの間の主な構造上の違いは、衝突を解決するためDictionaryチェーン(ハッシュテーブルバケットごとに項目のリストを維持する)に依存しているのに対し、衝突解決のために再ハッシュHashtable使用します(衝突が発生すると、別のハッシュ関数を使用してキーをバケットにマッピングします)。 。

Hashtable.NET Framework 2.0以上を対象としている場合は、クラスを使用してもほとんどメリットがありません。によって効果的に廃止されDictionary<TKey, TValue>ます。


21
Jon- @チェーンと再ハッシュがhere-深さで説明されmsdn.microsoft.com/en-us/library/ms379571(VS.80).aspx
RichardOD

あなたがた両方に感謝します。Richardが投稿したそのページを見つけたばかりです...チェーンについて質問するつもりでしたが、MSDNサイトは実際に役に立ちました!
ジョン

6
@Mehrdad-衝突がどのように解決されるかについて私に明確ではないことはこれです:複数のキーが同じハッシュをもたらす可能性がある場合、ルックアップで正しい値を取得していることをどのように確認しますか、つまり、関数はどの要素にどのように知っているのですか?戻る?で msdn.microsoft.com/en-us/library/ms379571%28VS.80%29.aspxそれはHashtableのクラスで行われているように、衝突時に再プローブよりもむしろ、辞書は、単にチェーン」、任意の衝突を語りますバケツのリストに。」これは、ディクショナリを使用する場合、衝突は開発者が心配する必要がないことを意味しますか?
Howiecamp

6
@Howiecamp:これはとそれほど変わらないHashtable。ハッシュテーブルは、エントリに3つの情報(キーハッシュ、キー自体、および値)を格納します。ハッシュが等しいアイテムの場合は、リストを走査して、キーが等しいアイテムを見つけ、その値を返す必要があります。これはかなり当てはまりHashtableます。Dictionary普通に使っている開発者なら、心配する必要はありません。
Mehrdad Afshari、2010

@Mehrdad明確に言うと、HashtableオブジェクトとDictionaryオブジェクトの両方がキー自体を格納し、どちらも開発者からの衝突を隠していますか?
Howiecamp 2010

111

今は何も意味がないと思います。しかし、単に立ち寄る人々のための参考のために

パフォーマンステスト-SortedList対SortedDictionary対辞書対ハッシュテーブル

メモリ割り当て:

メモリ使用パフォーマンステスト

挿入に使用された時間:

挿入にかかった時間

アイテムを検索する時間:

アイテムを検索する時間


非常に興味深いのは、ソートされたリストがハッシュテーブルよりも高速に検索できることです。ハッシュテーブルはO(1)とソートされたリストO(logn)だと思いました。どうやらハッシュテーブルはひどい。絶対に使わない。
ジョンヘンケル

@JohnHenckelいいえ、ソートされたリストは検索が遅くなります。パフォーマンス係数が大きいほど、パフォーマンスとメモリ使用量が向上します。したがって、並べ替えられたリストは、グラフによるとメモリ使用量が最も優れていますが、挿入やルックアップなどの他の領域では不十分です。
C0DEF52

31

ハッシュテーブルと辞書の違い

辞書:

  • 存在しないキーを見つけようとすると、辞書はエラーを返します。
  • ボックス化とボックス化解除がないため、Hashtableよりも辞書が高速です。
  • ディクショナリはジェネリック型であるため、どのデータ型でも使用できます。

ハッシュ表:

  • 存在しないキーを見つけようとすると、ハッシュテーブルはnullを返します。
  • ボクシングとアンボクシングが必要なため、ハッシュテーブルは辞書よりも低速です。
  • Hashtableはジェネリック型ではありません。

24

もう1つの重要な違いは、Hashtableタイプはロックフリーの複数のリーダーと1つのライターを同時にサポートするのに対して、Dictionaryはサポートしないことです。


8
コンカレントディクショナリがサポートされます(.Net 4.0)
タミルマラン

1
この答えが理解できるかどうかわかりません。ここを見ると、msdn.microsoft.com / en-us / library /…と書かれています。「複数のライターをサポートするには、Hashtableオブジェクトを読み取るスレッドがない場合、Hashtableのすべての操作は、Synchronizedメソッドによって返されるラッパーを介して行う必要があります。 」それは「ロックフリーの複数のリーダー」機能をかなり役に立たないように思われるので、辞書と同じように、ハッシュテーブルへのすべてのアクセスをロックする必要に戻ります。
RenniePet

16

MSDN記事:「Dictionary<TKey, TValue>クラスが同じ機能持つHashtableクラスA。 Dictionary<TKey, TValue> (以外の特定のタイプのがObject)よりも良好な性能有する Hashtableの要素がので、値型のためのHashtableタイプであるObjectと記憶する場合、または、従って、ボクシング、典型的にアンボクシングが発生値タイプを取得しています。」

リンク:http : //msdn.microsoft.com/en-us/library/4yh14awz(v=vs.90).aspx


11

どちらも実質的に同じクラスです(逆アセンブリを見ることができます)。HashTableは、.Netがジェネリックスを持つ前に最初に作成されました。辞書は、しかし、一般的なクラスであり、強力なタイピングの利点を提供します。辞書はあなたに何も使う必要がないので、私はHashTableを決して使用しません。


8

もう1つの重要な違いは、Hashtableスレッドセーフであることです。Hashtable複数のリーダー/シングルライター(MR / SW)のスレッドセーフティが組み込まれているため、1つのライターHashtableをロックせずに複数のリーダーと一緒に使用できます。Dictionaryスレッドセーフがない場合、スレッドセーフが必要な場合は、独自の同期を実装する必要があります。

さらに詳しく説明するには:

Hashtable、Synchronizedプロパティを通じてスレッドセーフを提供します。Synchronizedプロパティは、コレクションのスレッドセーフラッパーを返します。ラッパーは、追加または削除操作のたびにコレクション全体をロックすることによって機能します。したがって、コレクションにアクセスしようとする各スレッドは、その順番が1つのロックを取得するまで待機する必要があります。これはスケーラブルではなく、大規模なコレクションのパフォーマンスを大幅に低下させる可能性があります。また、設計は競合状態から完全に保護されていません。

、などの.NET Framework 2.0コレクションクラスは List<T>Dictionary<TKey, TValue>スレッド同期を提供しません。アイテムが複数のスレッドで同時に追加または削除される場合、ユーザーコードはすべての同期を提供する必要があります。タイプセーフとスレッドセーフが必要な場合は、.NET Frameworkで並行コレクションクラスを使用します。詳細はこちら。


3

辞書にはジェネリック型であるという利点があり、ボクシングの必要がないため、型安全で少し高速になります。次の比較表(同様のSO 質問の投稿で見つかった回答を使用して作成)は、ハッシュテーブル(またはその逆)で辞書をサポートする他のいくつかの理由を示しています。


1

常にオブジェクトがディクショナリに挿入された順序で返されるようにしたい場合は、

OrderedDictionary-値は整数インデックスを介してアクセスできます(アイテムが追加された順序で) SortedDictionary-アイテムは自動的にソートされます


0

辞書は一般的な強力な型であるため、辞書はハッシュテーブルよりも高速です。ハッシュテーブルは、オブジェクトをデータ型として受け取るため、ボックス化とボックス化解除につながるため、遅くなります。



4
@Arvandリンクが壊れています-販売中のドメイン。
RenniePet 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.