mapとunordered_mapのどちらを選択するのですか?


83

文字列をキーとしてデータをマッピングしたいとします。どのコンテナを選択するmap必要がありunordered_mapますか?unordered_mapより多くのメモリを消費するので、メモリは問題ではなく、問題は速度であると仮定しましょう。

unordered_map一般に、O(n)の最悪の場合でO(1)の平均計算量を与えるはずです。どのような場合にO(n)に到達しますか?いつmapよりも時間効率が良くなりunordered_mapますか?nが小さいときに起こりますか?

unordered_mapデフォルトのhaserVsでSTLを使用すると仮定します。地図。文字列がキーです。

毎回個々の要素にアクセスするのではなく、要素を反復処理する場合は、どちらを選択する必要がありmapますか?


3
マッピング内のアイテムを並べ替える必要がありますか?
一部のプログラマーは2012

どの実装がunordered_mapより多くのメモリを使用しますか?
ピーターウッド

通常は無視できますが、ハッシュマップには常にメモリオーバーヘッドがあります。
ypnos 2012

これはマイナーなポイントですが、反復について言及しているように、要素の挿入中に反復する場合は、unordered_mapよりもmapを優先する必要があることを指摘する価値があります。
ジョンマクファーレーン

回答:


67

実際には、メモリに問題がなければ、 unordered_mapがなければ、単一要素のアクセスが必要な場合は常に高速です。

最悪のケースは理論的であり、すべての要素を説明する単一のハッシュにバインドされています。これは実際的な関連性はありません。unordered_mapすぐに、少なくともログN同じハッシュに属する要素を持っているほど遅くなります。これも実際的な関連性はありません。いくつかの特別なシナリオでは、より均一な分布を保証する特定のハッシュアルゴリズムを使用できます。特定のパターンを共有しない通常の文字列の場合、付属の汎用ハッシュ関数unordered_mapも同様に優れています。

(イテレータを使用して)ソートされた方法でマップをトラバースする場合は、を使用できませんunordered_map。それどころか、mapそれを可能にするだけでなく、キーの近似に基づいてマップ内の次の要素を提供することもできます(lower_boundおよびupper_boundメソッドを参照)。


6
この答えはせいぜい誤解を招くものです。「unordered_mapは単一要素のアクセスに対して常に高速である」というのは真実ではありません。私が考えることができる唯一のことは、それが常により速く償却され漸近的になるということです。「償却」は、実際には重要な警告です。ある種のハッシュテーブルとして実装されていると仮定すると、ハッシュテーブルを正しく覚えていれば、要素を挿入して成長させると、Ω(n)演算で「しゃっくり」します。時々。これは、特定のアプリが許容できるものである場合とそうでない場合があります。
ドンハッチ

209
                       | map              | unordered_map
---------------------------------------------------------
element ordering       | strict weak      | n/a 
                       |                  |
common implementation  | balanced tree    | hash table
                       | or red-black tree|  
                       |                  |
search time            | log(n)           | O(1) if there are no hash collisions
                       |                  | Up to O(n) if there are hash collisions 
                       |                  | O(n) when hash is the same for any key
                       |                  |     
Insertion time         | log(n)+rebalance | Same as search
                       |                  | 
Deletion time          | log(n)+rebalance | Same as search
                       |                  | 
needs comparators      | only operator <  | only operator ==
                       |                  |
needs hash function    | no               | yes
                       |                  |
common use case        | when good hash is| In most other cases. 
                       | not possible or  | 
                       | too slow. Or when|
                       | order is required| 

6
一般的な実装についてのコメント:赤黒木は一種の平衡二分木(より具体的には一種の自己平衡二分探索木)です。
ハローグッバイ2015年

2
リバランスにかかる時間はlog(n)
mtk 2016年

すべての要素を反復処理するのはどうですか?
Shashwat

7

どのような場合にO(n)に到達しますか?

すべての入力攪拌に対して同じハッシュ値を生成する(つまり、衝突を生成する)ような悪いハッシュ関数がある場合...

どのコンテナを選択する必要がありますか、mapまたはunordered_map?

それは常に要件とデータの種類/量の問題です。

マップがunordered_mapよりも時間効率が高くなるのはいつですか?

それはただ異なる構造です。典型的なユースケースに応じて、そのうちの1つを使用するように選択することをお勧めします(どのような種類のデータとその量を考慮に入れて)

nが小さいときはhppaenですか?

データ量が少ない場合は、すべてが特定のSTL実装に依存します...したがって、単純なベクトル/配列でさえ、連想コンテナよりも高速である場合があります...


7

どのコンテナを選択する必要がありますか、mapまたはunordered_map?unordered_mapはより多くのメモリを消費するので、メモリが問題ではなく、速度が問題であると仮定しましょう。

プロファイルしてから決定します。unordered_map一般的に高速ですが、ケースごとに異なります。

どのような場合にO(n)に到達しますか?

ハッシュが適切でなく、多数の要素が同じビンに割り当てられている場合。

マップがunordered_mapよりも時間効率が高くなるのはいつですか?nが小さいと起こりますか?

おそらくそうではありませんが、本当に気になる場合はプロファイルを作成してください。小さいサイズのコンテナがプログラムのボトルネックになる可能性は非常に低いようです。とにかく、そのような場合vector、線形検索を使用した単純な方が高速な場合があります。


決定する際に最も重要なことは、順序付けの要件とイテレータの無効化の欠如です。どちらかが必要な場合は、ほとんどを使用する必要がありますmap。それ以外の場合、unordered_map

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.