C++ std::string ajouter vs push_back()
C'est vraiment une question juste pour mon propre intérêt, je n'ai pas été en mesure de déterminer par le biais de la documentation.
Je vois sur http://www.cplusplus.com/reference/string/string/ qu'ajouter a la complexité:
"Quelconque, mais généralement linéaire dans la nouvelle longueur de la chaîne."
tout push_back() a la complexité:
"Non spécifié; Généralement amortis constante, mais jusqu'linéaire dans la nouvelle longueur de la chaîne."
Comme un jouet exemple, supposons que je voulais ajouter les caractères "toto" pour une chaîne de caractères. Serait
myString.push_back('f');
myString.push_back('o');
myString.push_back('o');
et
myString.append("foo");
montant exactement la même chose? Ou est-il une différence? Vous pourriez figure append serait plus efficace, car le compilateur ne sais combien de mémoire est nécessaire d'étendre la chaîne de caractères que le nombre spécifié de caractères, tandis que push_back peut-être besoin de sécuriser la mémoire à chaque appel?
myString += "foo";
que je pense que c'est plus "naturel", même si c'est le même que le append
appel.Mots-clés: "jusqu'à". Mais c'est dommage qu'ils n'ont pas d'état le cas typique pour
append
, que le pire.push_back
doit être amorti à temps constant, donc la probabilité de trois allocations pour chaque application que je suis au courant, c'est zéro. La plupart des start avec une certaine taille raisonnable (plus de 1 ou 2) et développer le sous-jacent de la mémoire tampon géométriquement (par un facteur de 1,5 ou 2 fois par l'augmentation de la taille).OriginalL'auteur Memento Mori | 2013-02-26
Vous devez vous connecter pour publier un commentaire.
En C++03 (pour laquelle la plupart d' "cplusplus.com"la documentation est écrite), les complexités ont été indéterminée en raison de la bibliothèque de maîtres d'œuvre ont été autorisés à faire du Copy-on-Write" ou "la corde" de style représentations internes pour les chaînes. Par exemple, une VACHE mise en œuvre peut exiger que la copie de l'ensemble de la chaîne si un caractère est modifié et il est le partage de passe.
En C++11, de la VACHE et de la corde implémentations sont interdits. Vous devez vous attendre constant amorti fois par caractère ajoutée ou linéaire amorti temps dans le nombre de caractères ajoutés pour permettre l'ajout d'une chaîne de caractères à la fin. Les exécutants peuvent encore faire relativement choses folles avec des chaînes de caractères (en comparaison, par exemple, de
std::vector
), mais la plupart des implémentations vont être limitées à des choses comme la "petite optimisation de la chaîne".En comparant
push_back
etappend
,push_back
prive l'implémentation sous-jacente potentiellement longueur utile des informations dont il pourrait utiliser pour préallouer de l'espace. D'autre part,append
nécessite qu'une mise en œuvre marcher au-dessus de l'entrée deux fois pour trouver la longueur, de sorte que le gain de performances ou de la perte va dépendre d'un certain nombre de inconnaissable des facteurs tels que la longueur de la chaîne avant de tenter de l'ajouter. Cela dit, la différence est probablement extrêmement Extrêmement EXTRÊMEMENT faible. Aller avecappend
pour cela-c'est beaucoup plus lisible.Toutefois, si vous voulez juste ajouter 1 char, il n'y a pas de
append(char)
de surcharge. Dans ce caspush_back()
peut être utilisé.bien sûr, mais ce serait une autre question 🙂
Savez-vous si le C++11/14/17 norme(s) jamais resserré les exigences de complexité sur
push_back
/append
/insert
pour les chaînes? Si non, êtes-vous sûr que la plupart des implémentations existantes sont tellement sympathiques? (J'ai vaguement souvenir d'avoir des problèmes le long de ces lignes dans le passé, mais peut-être que c'était juste une conséquence de la Vache mise en œuvre.)Je ne suis pas sûr de ce "resserrement" vous pourriez demander. Ils ont toujours été amorti sur une période de temps constante pour autant que je sais. Actuellement, il est N4606 23.2.3 [séquence.reqmts] /16 anguille.est/c++projet/séquence.reqmts#16
OriginalL'auteur Billy ONeal
D'en ajouter un avis ici.
Personnellement, je pense c'est mieux d'utiliser
push_back()
lors de l'ajout de caractères un par un à partir d'une autre chaîne. Par exemple:Si vous utilisez
append()
ici, je voudrais remplacerpush_back(it)
avecappend(1,it)
, ce qui n'est pas lisible pour moi.OriginalL'auteur Pei
J'ai eu le même doute, j'ai donc fait un petit test pour vérifier cette (g++ 4.8.5 avec C++11 profil sur Linux, Intel 64 bits sous VmWare Fusion).
Et le résultat est intéressant:
Pourrait être possible, c'est à cause de la longueur de la chaîne (de gros), mais l'opérateur + est très cher par rapport à la push_back et l'ajouter.
Il est également intéressant de noter que lorsque l'opérateur ne reçoit qu'un personnage (pas de chaîne), il se comporte de façon très similaire à la push_back.
Pour ne pas dépendre des pré-alloués variables, chaque cycle est défini dans un autre champ.
Remarque : le vCounter utilise simplement gettimeofday pour comparer les différences.
OriginalL'auteur user2583872
Oui, je pense également que le
append()
pour de meilleures performances pour les raisons que vous avez donné, et dans une situation où vous avez besoin d'ajouter une chaîne de caractères, à l'aide deappend()
(ouoperator+=
) est certainement préférable (au moins pas aussi parce que le code est plus lisible).Mais quelle est la Norme spécifie, c'est la complexité de l'opération. Et qui est généralement linéaire, même pour
append()
, car en fin de compte chaque caractère de la chaîne est ajoutée (et possible tous les personnages, si la réaffectation se produit) doit être copié (cela est vrai même simemcpy
ou similaires sont utilisés).Oui, bien sûr.
OriginalL'auteur jogojapan