std
はunordered_map
に実際のハッシュマップを持っているので、実際に存在するシステムでunordered_map
よりも古くmap
を使用する理由(またはいつ)を使用したいのか?すぐに見ることができない明らかな状況はありますか?
既に言及 のように、map
はソートされた方法で要素を反復することができますが、unordered_map
はできません。これは、コレクション(アドレス帳など)の表示など、多くの状況で非常に重要です。これは、(1)find()
によって返されるイテレータから反復を開始する、または(2)lower_bound()
などのメンバー関数の存在など、他の間接的な方法でも現れます。
また、最悪の場合searchの複雑さにいくつかの違いがあると思います。
map
の場合、O(lg N)
unordered_map
の場合、O(N)[このmayは、ハッシュ関数が良くないためにハッシュ衝突が多すぎる場合に発生します。]
同じことが、最悪の場合deletionの複雑さにも当てはまります。
上記の回答に加えて、unordered_map
が一定速度(O(1)
)であるという理由だけで、map
(次数log(N)
)よりも高速であることも意味しないことに注意してください。 。特にN
は2に制限されているため、定数はlog(N)
よりも大きくなる可能性があります32 (または264)。
そのため、他の回答(map
は順序を維持し、ハッシュ関数は難しい場合があります)に加えて、map
の方がパフォーマンスが高い可能性があります。
たとえば、私が ブログ投稿 で実行したプログラムでは、VS10ではstd::unordered_map
がstd::map
よりも遅いことがわかりました(ただし、boost::unordered_map
は両方よりも高速でした)。
3番目から5番目のバーに注意してください。
これは、GoogleのChandler Carruthによる CppCon 2014講義 によるものです。
std::map
は(多くの人が考えている)パフォーマンス指向の作業には役に立たない:O(1)で償却したアクセスが必要な場合は、適切な連想配列を使用します(または1つがない場合はstd::unorderded_map
) ;ソートされた順次アクセスが必要な場合は、ベクトルに基づいたものを使用してください。
また、std::map
はバランスの取れたツリーです。信じられないほど頻繁にトラバースするか、バランスを取り直す必要があります。これらはそれぞれ、キャッシュキラーとキャッシュアポカリプスの操作です... std::map
に対してNOとだけ言ってください。
効率的なハッシュマップの実装に関する this SO question に興味があるかもしれません。
(PS-std::unordered_map
は、リンクリストをバケットとして使用するため、キャッシュに適さない。)
マップ内のアイテムをソート順に繰り返す必要があるstd::map
を使用することは明らかだと思います。
また、ハッシュ関数(一般的に非常に直感的ではない)の代わりに、比較演算子(直感的)を作成する場合にも使用できます。
非常に大きなキー、おそらく大きな文字列があるとします。大きな文字列のハッシュ値を作成するには、文字列全体を最初から最後まで処理する必要があります。キーの長さに対して少なくとも直線的な時間がかかります。ただし、キーの>
演算子を使用してバイナリツリーのみを検索する場合、最初の不一致が見つかった場合、各文字列比較は返すことができます。これは通常、大きな文字列では非常に早い段階です。
この推論は、std::unordered_map
およびstd::map
のfind
関数に適用できます。キーの性質がハッシュを生成するのに時間がかかる場合(std::unordered_map
の場合)、バイナリ検索を使用して要素の場所を見つけるのにかかる時間(std::map
の場合) )、std::map
でキーを検索する方が高速です。これが当てはまるシナリオは簡単に考えられますが、実際には非常にまれです。