réduire la capacité d'un vecteur stl
Est-il un moyen de réduire la capacité d'un vecteur ?
Mon code insère des valeurs dans un vecteur (ne connaissant pas leur nombre à l'avance), et
quand cela se termine, les vecteurs sont utilisés uniquement pour les opérations de lecture.
Je suppose que je pourrais créer un nouveau vecteur, faire un .reseve() avec la taille et la copie
les articles, mais je n'aime pas vraiment le supplément de l'opération de copie.
PS: je n'ai pas de soins pour une solution portable, aussi longtemps que cela fonctionne pour gcc.
- Juste une remarque, reserve() n'est pas nécessairement réservons le montant exact que vous transmettez; il se réserve d'un montant supérieur ou égal au montant que vous avez passer à la réserve).
- Notez que le swap idiome ne effectuer une copie. Je ne sais pas si GCC est une extension pour libérer inutilisés mémoire réservée. À mon avis, une telle méthode devrait être dans la norme pour vector<>.
- Envisagez d'utiliser un deque au lieu de vecteur. C'est presque aussi rapide que vecteur de mais ne conserve pas les données dans les états contigus des blocs et il n'a pas besoin de réserver()
- Un vecteur n'a pas besoin de réserver() soit, c'est juste plus efficace de le faire plutôt que de continuer à élargir sa longueur, au besoin, pendant push_back()s.
- Plus spécifique à la question de la réserve(), c'est qu'une deque n'a pas besoin de O(N) sur une capacité de seulement O(1) sur-capacité. Un vecteur besoins en O(N) au cours de capacité lors d'un redimensionnement de lui-même, afin de mettre en œuvre l'exigence d'insertion à la fin est amorti O(1) fois. C'est pourquoi deque est une bonne suggestion.
Vous devez vous connecter pour publier un commentaire.
L'échange le contenu avec un autre vecteur de swaps de la capacité.
Swap() ne changer la structure de données interne.
vector(v).capacity() == v.capacity()
toujours détient peut encore être compatible). Sanscapacity() == size()
de garantie (ou au moins une sorte decapacity() < size() + k
garantie),vector<T>(v).swap(v)
peut en fait entraîner aucune réduction.std::vector<T> temp; std::swap(temp, v);
? Est le membre de swap plus efficace en quelque sorte?Avec C++11, vous pouvez appeler la fonction membre
shrink_to_fit()
. Le projet de norme section 23.2.6.2 dit:Aller regarder Scott Meyers Efficace STL point 17.
Fondamentalement, vous ne pouvez pas réduire la taille de stockage d'un
std::vector
.resize()
etreseve()
permettra jamais de réduire l'empreinte mémoire d'un conteneur. Le "truc" est de créer un nouveau conteneur de la taille, de copier les données et échange avec le conteneur actuel. Si nous tenons pour effacer un réservoir à l'extérieur c'est tout simplement:Si nous avons pour copier les données, puis nous avons besoin de faire de la copie:
Ce que cela ne crée un vecteur avec les données de l'ancien, de faire de la copie qui serait nécessaire à toute opération qui a pour effet dont vous avez besoin. Puis l'appel de
swap()
va juste changer les tampons internes entre les objets. À la fin de la ligne, le vecteur temporaire qui a été créé est supprimé, mais il a le courage de l'ancien vecteur et l'ancien vecteur a le courage de la nouvelle copie qui est la taille exacte dont nous avons besoin.La idiomatiques solution est de permuter avec un nouvellement construit vecteur.
Edit: j'ai mal lu la question. Le code ci-dessus va effacer le vecteur. L'OP veut garder les éléments intacte, ne se rétrécir
capacity()
àsize()
.Il est difficile de dire si aJ code faire. Je doute qu'il y est de solution portable. Pour
gcc
, vous aurez à prendre un regard sur leur mise en oeuvre particulière devector
.modifier: j'ai Donc jeté un coup d'oeil libstdc++ mise en œuvre. Il semble que aJ est la solution sera de fait le travail.
Voir la source, la ligne 232.
Non, vous ne pouvez pas réduire la capacité d'un vecteur sans les copier. Toutefois, vous pouvez contrôler combien la nouvelle répartition de la croissance par la vérification de la capacité de() et de l'appel de la réserve() à chaque fois que vous insérez quelque chose. Le comportement par défaut pour les std::vector est de renforcer sa capacité par un facteur de 2 à chaque fois de nouvelles capacités est nécessaire. Vous pouvez la croissance, de par votre propre magie ratio:
Si vous êtes dans un très orthodoxe des techniques, vous pouvez toujours passer dans votre propre allocateur et de faire tout ce que vous devez faire pour récupérer de la capacité inutilisée.
Je ne dis pas que GCC ne pouvais pas avoir une méthode pour faire ce que vous voulez sans une copie, mais il serait difficile à mettre en oeuvre (je pense) parce que les vecteurs besoin d'utiliser un
Allocator
objet d'allouer et de libérer de la mémoire et de l'interface pour uneAllocator
ne comprend pas unreallocate()
méthode. Je ne pense pas qu'il serait impossible de le faire, mais il peut être difficile.Si vous êtes inquiet à propos de la surcharge de votre vecteur alors peut-être que vous devriez être à la recherche à l'aide d'un autre type de structure de données. Vous avez mentionné qu'une fois que votre code est fait de l'initialisation du vecteur, il devient un lire seul processus. Je suggère d'aller avec un open ended tableau qui permettra au programme de décider de sa capacité au moment de la compilation. Ou peut-être une liste liée serait plus adapté à vos besoins.
Crois-moi savoir si je suis complètement mal compris ce que vous aviez à.
-UBcse
Vieux thread, je sais, mais au cas où quelqu'un est d'affichage dans l'avenir.. il y a shrink_to_fit() en C++11, mais depuis, c'est un non-contraignant de la demande, le comportement dépendra de sa mise en œuvre.
Voir: http://en.cppreference.com/w/cpp/container/vector/shrink_to_fit
Obtenir la "Efficace STL" livre de Scott Myers. Il dispose d'un élément de jus sur la réduction du vecteur de la capacité.