Nettoyer le vecteur à chaque itération de la boucle. Quel est le moyen le plus efficace en termes de mémoire?

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

Question

J'ai une question sur std :: vector.

J'ai un algorithme très gourmand en mémoire. J'imagine que prévoir la taille des vecteurs et réserver suffisamment de mémoire pour les vecteurs m'aidera beaucoup à réduire l'utilisation de la mémoire.

Lequel des choix suivants est le meilleur:

for ( ... ) {
  std::vector<Type> my_vector;
  my_vector.reserve(stuff_count);
  // Do stuff , and append stuff to my_vector.
}

Ou ceci:

std::vector my_vector;
for ( ... ) {
  my_vector.clear();
  my_vector.reserve(stuff_count);
  // Do stuff , and append stuff to my_vector.
}

S'il vous plaît, dites-moi lequel est le meilleur ou s'il existe une meilleure façon de le faire.

Merci beaucoup d'avance!

Était-ce utile?

La solution

Avec la première variante, vous réaffectez la mémoire tampon du vecteur à chaque itération, ce qui est généralement très coûteux. Dans la deuxième variante, vous ne réaffectez que de temps en temps. La deuxième variante est préférable car la vitesse est une priorité pour vous.

Vous ne savez pas très bien d'où provient le nombre d'éléments. Vous pourrez peut-être même calculer rapidement le nombre maximal d’éléments pour toutes les itérations, définir la taille du tampon et éviter toute réaffectation.

Autres conseils

  

Je prévois que prévoir la taille des vecteurs et réserver suffisamment de mémoire pour les vecteurs m'aidera beaucoup à réduire l'utilisation de la mémoire.

Essayez d’agir comme un ingénieur et non comme une diseuse de bonne aventure. Créez un test et mesurez la différence.

Le deuxième pourrait être un peu plus rapide, mais je trouve le premier plus propre.

Les différences de code étant triviales, pourquoi ne pas tester les deux approches et voir celle qui convient le mieux à votre application particulière?

Cela dépend un peu de la manière dont Type doit être construit / détruit, je dirais. S'il s'agit d'un POD qui ne nécessite pas de destruction, vous pouvez ignorer clear (), qui appelle tous les destructeurs d'une boucle et l'utiliser à la place comme un tableau statique:

std::vector<Type> my_vector(size);
for (...)
{
  int index = 0;
  // Do stuff
  my_vector[index] = some_value;
}

(Avertissement: code non testé)

  

... réservant assez de mémoire pour la   les vecteurs à l'avance m'aideront beaucoup   avec réduction de l'utilisation de la mémoire

euh ... quoi?! Cela n'a aucun sens. La réservation de mémoire n'aide en aucune manière à réduire l'utilisation de la mémoire. Cela évite le besoin de réallocation constante, ce qui accélère les choses, mais en ce qui concerne l'utilisation , vous n'obtenez aucun avantage.

Le second utilisera la mémoire maximale de toutes les utilisations de celle-ci à travers la boucle, c'est-à-dire la taille maximale des types de stuff_count. std :: vector :: clear () ne libère pas nécessairement de mémoire . Par exemple, si vous appelez std :: vector :: capacity () avant et après std :: vector :: clear () , une implémentation conforme standard pourrait renvoyer la même valeur.

Au mieux, vous réduirez le nombre d'allocations de mémoire avec le schéma ci-dessus. Mais vous ne réduirez certainement pas l'empreinte mémoire à aucun moment. Si vous souhaitez réduire la quantité de mémoire réservée, vous devez utiliser l'idiome d'échange vectoriel:

std::vector<type>().swap(my_vector);
my_vector.reserve(stuff_count); 

Ou votre première solution, puisque l'effet global sera le même.

Si vous devez faire beaucoup d’ajouts, utilisez std :: deque au lieu de std :: vector et utilisez simplement "push_back".

que diriez-vous?

std::vector<DataType> my_vector;
my_vector.resize(sizeof(yourData));
memcpy(reinterpret_cast<char*>(&my_vector), &yourData, sizeof(yourData));
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top