7
votes

STD :: One Overked_Map très haute mémoire

hier j'ai essayé d'utiliser std :: unomment_map code> et ce code m'a confondu quelle mémoire il utilisait.

typedef list<string> entityId_list;
struct tile_content {
   char cost;
   entityId_list entities;
};
unordered_map<int, tile_content> hash_map;

for (size_t i = 0; i < 19200; i++) {
   tile_content t;
   t.cost = 1;
   map[i] = t;
}


1 commentaires

Je voulais juste noter qu'une carte non ordonnée peut contenir des centaines de mégaoctets, même lorsque aucun article n'est stocké à l'intérieur (lorsque vous effacez via des itérateurs, car si la carte REDASH, l'itérateur devient invalide) Voir ce rapport de bogue (ce qui peut aussi bien affecter Mise en œuvre Microsoft): svn.boost.org/trac/boost/ticket/11419


3 Réponses :


11
votes

Le Structure ONUERDED_MAP est conçu pour contenir un grand nombre d'objets d'une manière qui fabrique des ajouts, des suppresses, des recherches et des traverser sans commande efficace. Il n'est pas censé être efficace de la mémoire pour les petites structures de données. Pour éviter les peines associées à la redimensionnement, il alloue de nombreuses têtes de chaîne de hachage quand elle est créée pour la première fois.


0 commentaires

7
votes

Cela ne signifie pas nécessairement que la carte de hachage utilise tant de mémoire, mais que le processus a demandé que beaucoup de mémoire du système d'exploitation.

Cette mémoire est ensuite utilisée pour satisfaire aux demandes MALLOC / NOUVEAUX Demandes par le programme. Certains (ou surtout, je ne suis pas sûr de cela) Les allocateurs de la mémoire nécessitent plus de mémoire du système d'exploitation que nécessaire à ce moment-là pour l'efficacité.

Pour savoir combien de mémoire est utilisée par le non-ordonné_map, j'utiliserais un profileur de mémoire comme PerfTools .


0 commentaires

10
votes

C'est environ 6 Mo pour ~ 20k objets, donc 300 octets par objet. Étant donné que la table de hachage peut bien être dimensionnée pour avoir plusieurs fois plus de seaux que les entrées de courant, chaque godet peut être un pointeur sur une liste ou un vecteur d'objets en collision, chaque allocation de tas impliquée dans tout cela a probablement été arrondi au plus proche. Puissance de deux, et vous avez débogué sur lequel peut générer un certain ballon supplémentaire, tout cela me semble bien.

Quoi qu'il en soit, vous n'allez pas obtenir de sympathie pour la mémoire ou l'efficacité de la CPU de quoi que ce soit dans la construction de débogage ;-p. Microsoft peut injecter n'importe quel pont qu'ils aiment là-bas et l'utilisateur n'a aucun droit d'attentes autour de la performance. Si vous trouvez que c'est mauvais dans une construction optimisée, vous avez quelque chose à parler.

Plus généralement, comment ça échoue avec la taille () est très important, mais il est tout à fait légitime de se demander comment un programme irait avec un grand nombre de cartes non ordonnées relativement petites. Ça vaut la peine de noter que ci-dessous une certaine taille () même la force brute recherche dans un vecteur, des recherches binaires dans un vecteur trié ou un arbre binaire peut exacerber une carte sans ordonnée, tout en étant plus efficace de mémoire. .


2 commentaires

Pouvez-vous donner une raison pour la dernière phrase?


@Andrew: Les principaux avantages de performance des vecteurs triés sont des valeurs de mémoire contiguës et des valeurs sur place, tandis que Unorded_map Les implémentations ont tendance à allouer de manière dynamique des nœuds distincts et doivent les suivre des pointeurs pendant les opérations; Les opérations dans les arbres binaires et les vecteurs triés impliquent O (journal 2 N) ' << / code>' '' '' '' 'tandis que Opérations ONUORDED_MAP nécessite un appel de fonction de hachage (ce qui peut être coûteux Mais n'est fait qu'une fois par opération et peut être orchestré pour se produire une fois par valeur) et == `comparaisons. Comme toujours, mesurez vos données et utilisation réelles lorsque vous vous souciez.