web-dev-qa-db-fra.com

C ++ moyen le plus rapide d'effacer ou d'effacer un vecteur

J'ai un code où je remplis régulièrement un vecteur avec entre 0 et 5000 éléments. Je sais que le maximum ne dépasse jamais 5000. Au lieu d'initialiser le vecteur plusieurs fois, je voudrais le faire une seule fois

vector<struct> myvector;
myvector.reserve(5000);

Cependant, pour remplir à nouveau le vecteur, je dois d'abord effacer le vecteur sans altérer sa capacité. Donc généralement j'appelle myvector.clear ();

Il s'agit d'une opération O(n). Y a-t-il quelque chose de simple que je puisse faire pour augmenter les performances de ceci ou est-ce à peu près le meilleur qu'il obtiendra?

34
user788171

Si votre structure a un destructeur non trivial, alors cela doit être appelé pour tous les éléments du vecteur, quelle que soit la façon dont il est vidé. Si votre structure n'a qu'un destructeur trivial, le compilateur ou l'implémentation de bibliothèque standard est autorisé à optimiser le processus de destruction et à vous donner une opération O(1)).

39
Vaughn Cato

Le coût de clear() dépend en grande partie de ce que sont les objets stockés, et en particulier s'ils ont un destructeur trivial. Si le type n'a pas de destructeur trivial, alors l'appel doit détruire tous les objets stockés et c'est en fait une opération O(n), mais vous ne pouvez vraiment rien faire de mieux.

Maintenant, si les éléments stockés ont des destructeurs triviaux, alors l'implémentation peut optimiser le coût et clear() devient une opération bon marché O(1) (juste réinitialiser la taille - end pointeur).

N'oubliez pas que pour comprendre la complexité asymptotique, vous devez savoir de quoi elle parle. Dans le cas de clear() il représente le nombre de destructeurs appelés, mais si le coût (caché) est 0, alors l'opération est un no-op.

Tout ce que vous faites pour supprimer les éléments existants du vecteur doit (potentiellement) invoquer le destructeur de chaque élément détruit. Par conséquent, du point de vue du conteneur, le mieux que vous puissiez espérer est la complexité linéaire.

Cela ne laisse que la question du type d'articles que vous stockez dans le vecteur. Si vous stockez quelque chose comme int que le compilateur peut/saura à l'avance n'a pas de destructeur à invoquer, les chances sont au moins assez bonnes que la suppression se retrouve avec une complexité constante.

Je doute cependant que la modification de la syntaxe (par exemple, clear() vs resize() vs erase(begin(), end())) fera une différence significative. La syntaxe ne change pas le fait que (en l'absence de thread) l'invocation de N destructeurs est une opération O(N).

10
Jerry Coffin