iterator insert ( iterator position, const T& x );
Est la déclaration de fonction de l'opérateur d'insertion de std::Vector
classe.
Le type de retour de cette fonction est un itérateur pointant vers l'élément inséré. Ma question est, compte tenu de ce type de retour, quel est le moyen le plus efficace (cela fait partie d'un programme plus large que j'exécute où la vitesse est essentielle, donc je recherche le le plus moyen de calcul efficace ) d'insertion au début. Est-ce le suivant?
//Code 1
vector<int> intvector;
vector<int>::iterator it;
it = myvector.begin();
for(int i = 1; i <= 100000; i++){
it = intvector.insert(it,i);
}
Ou,
//Code 2
vector<int> intvector;
for(int i = 1; i <= 100000; i++){
intvector.insert(intvector.begin(),i);
}
Essentiellement, dans le code 2, est le paramètre,
intvector.begin()
"Coûteux" à évaluer par rapport à l'utilisation de l'itérateur retourné dans le code 1 ou les deux devraient-ils être tout aussi bon marché/coûteux?
L'efficacité de l'obtention du point d'insertion n'aura aucune importance - elle sera éclipsée par l'inefficacité de mélanger constamment les données existantes à chaque fois que vous effectuez une insertion.
Utilisez std :: deque pour cela, c'est pour cela qu'il a été conçu.
Si l'un des besoins critiques de votre programme est pour insérer des éléments au début d'un conteneur: alors vous devez utiliser un std::deque
et non un std::vector
. std::vector
ne sert qu'à insérer des éléments à la fin.
D'autres conteneurs ont été introduits dans C++ 11. Je devrais commencer à trouver un graphique mis à jour avec ces nouveaux conteneurs et l'insérer ici.
Un vieux fil, mais il est apparu au bureau d'un collègue comme premier résultat de recherche pour une requête Google.
Il existe une alternative à l'utilisation d'un deque qui mérite d'être envisagée:
std::vector<T> foo;
for (int i = 0; i < 100000; ++i)
foo.Push_back(T());
std::reverse( foo.begin(), foo.end() );
Vous utilisez toujours un vecteur beaucoup plus conçu que deque pour les performances. De plus, les swaps (qui sont les utilisations inverses) sont assez efficaces. En revanche, la complexité, bien que toujours linéaire, est augmentée de 50%.
Comme toujours, mesurez avant de décider quoi faire.
Le plus probable deque
est la solution appropriée comme suggéré par d'autres. Mais juste pour être complet, supposons que vous devez effectuer cette insertion frontale une seule fois, qu'ailleurs dans le programme, vous n'avez pas besoin d'effectuer d'autres opérations sur le front, et qu'autrement vector
fournit l'interface dont vous avez besoin . Si tout cela est vrai, vous pouvez ajouter les éléments avec le très efficace Push_back
puis reverse
le vecteur pour tout mettre en ordre. Cela aurait une complexité linéaire plutôt que polynomiale comme lors de l'insertion à l'avant.
Si vous recherchez un moyen d'insertion efficace sur le plan informatique, vous voudrez probablement utiliser un deque au lieu d'un vecteur.
Je pense que vous devriez changer le type de votre conteneur si vous voulez vraiment insérer des données au début. C'est la raison pour laquelle le vecteur n'a pas de fonction membre Push_front ().
Lorsque vous utilisez un vecteur, vous connaissez généralement le nombre réel d'éléments qu'il contiendra. Dans ce cas, réserver le nombre d'éléments nécessaires (100000 dans le cas que vous montrez) et les remplir en utilisant le []
L'opérateur est le moyen le plus rapide. Si vous avez vraiment besoin d'un insert efficace à l'avant, vous pouvez utiliser deque
ou list
, selon vos algorithmes.
Vous pouvez également envisager d'inverser la logique de votre algorithme et de l'insérer à la fin, ce qui est généralement plus rapide pour les vecteurs.
Intuitivement, je suis d'accord avec @Happy Green Kid Naps et j'ai effectué un petit test montrant que pour les petites tailles (1 << 10 éléments d'un type de données primitif), cela n'a pas d'importance. Pour les contenants plus grands (1 << 20), cependant, std::deque
semble être plus performant que l'inversion d'un std::vector
. Donc, comparez avant de vous décider. Un autre facteur pourrait être le type d'élément du conteneur.
Résultats: