45 votes

Comment estimer la consommation de mémoire de std :: map?

Par exemple, j'ai un std :: map avec une taille connue (A) et sizeof (B), tandis que la carte a N entrées à l'intérieur. Comment estimeriez-vous son utilisation de la mémoire? Je dirais que c'est quelque chose comme

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

Mais quel est le facteur? Formule différente peut-être?

Peut-être est-il plus facile de demander une limite supérieure?

37voto

Diomidis Spinellis Points 8417

L'estimation serait plus proche de l'

(sizeof(A) + sizeof(B) + ELEMENT_OVERHEAD) * N + CONTAINER_OVERHEAD

Il y a une surcharge pour chaque élément que vous ajoutez, et il y a aussi une charge fixe pour le maintien de la structure de données utilisée pour les données de la structure de stockage de la carte. C'est typiquement un arbre binaire, comme un Rouge-l'Arbre Noir. Par exemple, dans le GCC C++ STL mise en oeuvre ELEMENT_OVERHEAD serait sizeof(_Rb_tree_node_base) et CONTAINER_OVERHEAD serait sizeof(_Rb_tree). La figure ci-dessus, vous devez également ajouter les frais généraux de gestion de la mémoire structures utilisées pour le stockage de la carte et les éléments.

Il est probablement plus facile pour arriver à une estimation par la mesure de votre code de la consommation de mémoire pour diverses grandes collections.

20voto

Xavier Nodet Points 2498

Vous pouvez utiliser MemTrack , par Curtis Bartley. Il s'agit d'un allocateur de mémoire qui remplace celui par défaut et peut suivre l'utilisation de la mémoire jusqu'au type d'allocation.

Un exemple de sortie:

 -----------------------
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%
 

16voto

dirkgently Points 56879

Si vous voulez vraiment savoir l'exécution de la mémoire, de l'utilisation d'un allocateur personnalisé et de le transmettre lors de la création de la carte. Voir Josuttis livre et cette page de son (pour un allocateur personnalisé).

C'est peut-être plus facile de demander à la limite supérieure?

La limite supérieure dépend de l'exacte mise en œuvre (par exemple, la variante particulière de l'équilibre de l'arbre utilisé). Peut-être, pouvez-vous nous dire pourquoi vous avez besoin de cette information afin que nous puissions mieux?

8voto

user2548100 Points 610

J'ai récemment eu besoin de répondre à cette question pour moi-même, et a simplement écrit un petit programme de test en utilisant std::map j'ai compilé sous MSVC 2012 en mode 64 bits.

Une carte avec 150 millions de nœuds trempés jusqu' ~ 15GO, ce qui implique le 8 octets L, 8 octets R, 8 octets clé de type int, et 8 octets de donnée, pour un total de 32 octets, trempés jusqu'à environ 2/3rds de la carte mémoire pour les noeuds internes, en laissant 1/3ème de feuilles.

Personnellement, j'ai trouvé ceci pour être étonnamment pauvres efficacité de mémoire, mais elle est ce qu'elle est.

Espérons que cela fait pour une pratique de la règle-de-pouce.

PS: La surcharge d'un std::map, c'est que d'un seul nœud de la taille AFAICT.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X