26

std::unordered_map大量のデータを保存するためにfromgnu+50xを使用しています。使用するスペースの合計を制限できるため、多数の要素にスペースを事前に割り当てたいと思います。

私がしたいのは電話です:

std::unordered_map m;
m.resize(pow(2,x));

ここで、xは既知です。

std::unordered_mapこれをサポートしていません。std::unordered_map最終的には標準の一部になるので、可能であれば使用したいと思います。

その他の制約:

マップの信頼できるO(1)アクセスと変更が必要です。必要なハッシュ関数と比較関数はすでに非標準であり、いくらか高価です。O(log n)ミューテーション(と同様std::map)はコストがかかりすぎます。

->高価なハッシュと比較も、償却ベースの成長を非常に高価にします。追加の挿入ごとに、これらの関数からのO(n)演算が必要になります。これにより、指数関数的なストレージ要件にはO(n)の増加が必要になるため、アルゴリズムの実行時間に2次項が追加されます。

4

5 に答える 5

33
m.rehash(pow(2,x));

pow(2, x)が事前に割り当てたいバケットの数である場合。あなたもすることができます:

m.reserve(pow(2,x));

しかし、これpow(2, x)が挿入を計画している要素の数です。どちらの関数も、バケットを事前に割り当てるだけです。要素は挿入されません。そして、それらは両方ともあなたのユースケースに正確に使用されることを意図しています。

pow(2, x)注:バケットを正確に取得できるとは限りません。一部の実装では、2の累乗であるバケットの数のみを使用します。他の実装では、素数のバケットのみを使用します。さらに、バケット数に素数のサブセットのみを使用するものもあります。ただし、いずれの場合も、実装は必要なバケット数のヒントを受け入れてから、内部で次の許容可能なバケット数に切り上げる必要があります。

最新(N4660)が引数を指定するために使用する正確な表現は次のrehashとおりです。

a.rehash(n)事後条件: a.bucket_count() >= a.size() / a.max_load_factor() and a.bucket_count() >= n

この事後条件により、、bucket()_count() >= nおよびが。load_factor()以下のままであることが保証されmax_load_factor()ます。

その後reserve(n)、次のように定義されますrehash(n)

a.reserve(n):と同じa.rehash(ceil(n / a.max_load_factor()))

于 2011-05-05T23:56:25.167 に答える
4

順序付けされていないマップに事前に割り当てられたメモリがあることは重要ではないと思います。STLは、O(n)償却挿入時間であると予想されます。私の意見では、これがコードのボトルネックであることがわかるまで、独自のアロケータを作成する手間を省いてください。

于 2011-05-05T23:49:25.240 に答える
3

std::unordered_map希望どおりにメモリを割り当てるための独自のアロケータを作成することをお勧めします。

于 2011-05-05T23:38:40.663 に答える
1

コンストラクターは、 http: //en.cppreference.com/w/cpp/container/unordered_map/unordered_mapに従ってパラメーター「size_typebucket_count」を取ります

したがって、サンプルコードが言うことを実行する最も簡単な方法は次のとおりです。

std::unordered_map m{ pow(2,x) };

これは、構築時に予約されるバケットの数が定義されていないため、より効率的です。それ以外の場合は、後で予約を呼び出すときに割り当てを行ってから割り当てを解除する必要があります。

于 2016-10-07T18:21:10.543 に答える
-2

再ハッシュ予約の両方が機能するのは、マップされた値がどれだけのメモリを使用するかを事前に知っている場合だけだと思います。マップされた値が複雑であるか、サイズが動的に変化する場合(ベクトルなど)、独自の実装が必要になります。たとえば、メモリサイズが許せば、これまでに存在した可能性のある最大のコンテナを予約できます。

于 2016-01-14T21:12:24.137 に答える