どのように私はのstd ::マップのメモリ使用量を見積もることができますか?
質問
例えば、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_OVERHEAD
にsizeof(_Rb_tree_node_base)
されるとCONTAINER_OVERHEAD
はsizeof(_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の実装に応じて、異なるコンパイラ/プラットフォーム上で異なるサイズを持っているかもしれません。
なぜあなたはこのサイズが必要なのでしょうか?