どのように私はのstd ::マップのメモリ使用量を見積もることができますか?

StackOverflow https://stackoverflow.com/questions/720507

  •  23-08-2019
  •  | 
  •  

質問

マップは内部N個のエントリを有している

例えば、Iは、公知のsizeof(A)およびsizeof(B)とのstd ::マップを有しています。どのようにそのメモリ使用量を推定しますか? 私はそれが

のようなものだと言うだろう
(sizeof(A) + sizeof(B)) * N * factor

しかし、要因は何ですか?多分違う式?

多分それは上限をお願いする方が簡単です!

役に立ちましたか?

解決

推定値は

に近いだろう
(sizeof(A) + sizeof(B) + ELEMENT_OVERHEAD) * N + CONTAINER_OVERHEAD

は、追加する各要素のオーバーヘッドがあり、地図データ格納構造に使用されるデータ構造を維持するための固定オーバーヘッドもあります。これは、赤黒木するとして、一般的にバイナリツリーです。例えば、GCC C ++ STL実装ELEMENT_OVERHEADsizeof(_Rb_tree_node_base)されるとCONTAINER_OVERHEADsizeof(_Rb_tree)されるであろう。上の図に、あなたはまた、マップの要素を格納するために使用されるメモリ管理構造のオーバーヘッドを追加する必要があります。

これは、様々な大規模なコレクションのためにあなたのコードのメモリ消費量を測定することにより、推定に到着する方が簡単でしょう。

他のヒント

あなたはカーティスバートリーにより、 MemTrack を使用することができます。これは、デフォルトの1を置き換え、割り当ての種類までメモリ使用量を追跡することができ、メモリアロケータです。

出力の例:

-----------------------
Memory Usage Statistics
-----------------------

allocated type                        blocks          bytes  
--------------                        ------          -----  
struct FHRDocPath::IndexedRec          11031  13.7% 2756600  45.8%
class FHRDocPath                       10734  13.3%  772848  12.8%
class FHRDocElemPropLst                13132  16.3%  420224   7.0%
struct FHRDocVDict::IndexedRec          3595   4.5%  370336   6.2%
struct FHRDocMDict::IndexedRec         13368  16.6%  208200   3.5%
class FHRDocObject *                      36   0.0%  172836   2.9%
struct FHRDocData::IndexedRec            890   1.1%  159880   2.7%
struct FHRDocLineTable::IndexedRec       408   0.5%  152824   2.5%
struct FHRDocMList::IndexedRec          2656   3.3%  119168   2.0%
class FHRDocMList                       1964   2.4%   62848   1.0%
class FHRDocVMpObj                      2096   2.6%   58688   1.0%
class FHRDocProcessColor                1259   1.6%   50360   0.8%
struct FHRDocTextBlok::IndexedRec        680   0.8%   48756   0.8%
class FHRDocUString                     1800   2.2%   43200   0.7%
class FHRDocGroup                        684   0.8%   41040   0.7%
class FHRDocObject * (__cdecl*)(void)     36   0.0%   39928   0.7%
class FHRDocXform                        516   0.6%   35088   0.6%
class FHRDocTextColumn                   403   0.5%   33852   0.6%
class FHRDocTString                      407   0.5%   29304   0.5%
struct FHRDocUString::IndexedRec        1800   2.2%   27904   0.5%
あなたが本当に実行時のメモリフットプリントをお知りになりたい場合は、

、カスタムアロケータを使用してマップを作成するときにそれを渡します。 (カスタムアロケータのため)彼のこののページrel="noreferrer"> Josuttis氏の本や

  

多分それは上限をお願いする方が簡単です!

の上限は、正確な実装に依存するであろう(例えば、バランスのとれたツリーの特定の変異体が使用されます)。たぶん、あなたは私たちがよりよく助けることができるので、あなたは、この情報を必要とする理由をお聞かせすることができますか?

私は最近、自分のためにこの質問に答えるために必要な、と単純に私は64ビットモードでMSVC 2012でコンパイルのstd ::マップを使用して小さなベンチマークプログラムを書いています。

1.5億ノードとマップは、のの約2 / 3rdsを浸した32バイトの合計8バイトL、8バイトR、8バイトの整数キー、及び8バイトのデータを、意味〜15ギガバイトを、アップ浸し内部ノードのためのマップのメモリ、葉のために1 /第3回を残して。

個人的に、私は、これは驚くほど貧弱なメモリ効率であることが判明し、それはそれが何であるかです。

これは便利な経験則になり希望。

PS:STD ::マップのオーバーヘッドは、単一ノードのサイズAFAICTのものです。

式がより似ている

(sizeof(A) + sizeof(B) + factor) * N

の要因は、エントリごとのオーバヘッドです。 C ++マップは、典型的には、赤黒木として実装されています。これらは、バイナリツリーであるため、左/右のノードのために少なくとも二つのポインタが存在します。そこにもいくつかの実装のものになります - おそらく親ポインタと「色」のインジケータ、その要因は、

のようなものかもしれ
(sizeof( RBNode *) * 3 + 1) / 2

しかし、このすべては非常に実装依存である - あなたが本当にあなた自身のライブラリの実装のためのコードを検討する必要があることを確認するために見つけるために、

マップのサイズは、実際にマップの実装に依存します。あなたは彼らが提供しているSTLの実装に応じて、異なるコンパイラ/プラットフォーム上で異なるサイズを持っているかもしれません。

なぜあなたはこのサイズが必要なのでしょうか?

scroll top