Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

concatenation de chaine

6 réponses
Avatar
JBB
voici un petit bout de code

std::string s = "";
for (int i=0; i < 50000;i++) {
s = s + "jbb";
}

ce code met prete de 12 secondes a s'executer chez moi.

apres investigation j'arrive au code suivant:

std::strstream strm;
for (int i =0; i < LOOP ; i++){
strm << "jbb";
}
std::string s(strm.str(),strm.pcount());//j'ai rien trouvé de mieux (?)

qui lui est presque instantané !!
(en Java j'obtient le même phénomène en comparant String et StringBuffer).

questions:
pourquoi les std::string sont si lentes?
est ce que strstream est une classe "standard" ?

6 réponses

Avatar
JBB
Bonjour,


voici un petit bout de code

std::string s = "";
for (int i=0; i < 50000;i++) {
s = s + "jbb";
}

ce code met prete de 12 secondes a s'executer chez moi.

apres investigation j'arrive au code suivant:

std::strstream strm;
for (int i =0; i < LOOP ; i++){
strm << "jbb";
}
std::string s(strm.str(),strm.pcount());//j'ai rien trouvé de mieux (?)

qui lui est presque instantané !!
(en Java j'obtient le même phénomène en comparant String et StringBuffer).

questions:
pourquoi les std::string sont si lentes?
est ce que strstream est une classe "standard" ?


Merci,

Avatar
Michel Decima

voici un petit bout de code

std::string s = "";
for (int i=0; i < 50000;i++) {
s = s + "jbb";
}

ce code met prete de 12 secondes a s'executer chez moi.


Premier probleme:

s = s + "jbb";

ici, tu cree un temporaire en concatenant s et "jbb", et tu stocke
ce temporaire dans s. Vu qu'on est dans une grosse boucle, le programme
doit passer son temps a allouer/liberer ce temporaire. Tu peux
essayer a la place

std::string s;
for (int i=0; i < 50000;i++) {
s += "jbb"; // ou s.append( "jbb" );
}

Dans cette nouvelle version, on a toujours une reallocation du buffer
de s, qui va croitre au fur et a mesure. Comme tu peux prevoir la
capacité necessaire, tu peux faire une pre-allocation du buffer de s:

std::string s;
s.reserve( 50000 * strlen( "jbb" ) );
for (int i=0; i < 50000;i++) {
s += "jbb";
}


apres investigation j'arrive au code suivant:

std::strstream strm;
for (int i =0; i < LOOP ; i++){
strm << "jbb";
}
std::string s(strm.str(),strm.pcount());//j'ai rien trouvé de mieux (?)


strstream est périmé (et son usage est assez penible avec g++ par
exemple), il vaudrait mieux utiliser stringstream a la place:

std::ostringstream strm;
for (int i =0; i < LOOP ; i++){
strm << "jbb";
}
std::string s = strm.str();

qui lui est presque instantané !!
(en Java j'obtient le même phénomène en comparant String et StringBuffer).

questions:
pourquoi les std::string sont si lentes?


cf plus haut.

est ce que strstream est une classe "standard" ?


non, elle ne l'est pas (ou ne l'est plus).

Avatar
Jean-Marc Bourguet
JBB writes:

pourquoi les std::string sont si lentes?


Parce que tu fais beaucoup plus de chose dans le premier cas, y compris des
creations et destructions d'objets. Essaie
s += "jbb";
a la place de
s = s + "jbb";


est ce que strstream est une classe "standard" ?


Oui. Mais regarde stringstream (dans <sstream>) qui est beaucoup plus
adaptee pour un usage normal.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Jean-Marc Bourguet
Michel Decima writes:

James Kanze wrote:

Oui, elle l'est, et elle la sera sûrement aussi dans la
prochaine version de la norme.


Je croyais vraiment qu'elle ne l'etait pas, vu le comportement de gcc. Mais
si elle est standard, pourquoi gcc me dit qu'elle est "deprecated" ?


Parce qu'elle a ce statut dans la norme (ce qui est en fait un
avertissement que la prochaine version de la norme pourrait ne pas la
comporter. C'est peu vraissemblable que ce sera le cas. C'est encore
moins vraissemblable que les compilateurs se mettent à ne pas plus la
fournir).

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org


Avatar
Loïc Joly

Parce qu'elle a ce statut dans la norme (ce qui est en fait un
avertissement que la prochaine version de la norme pourrait ne pas la
comporter. C'est peu vraissemblable que ce sera le cas.


Et ce d'autant plus que certains membres du commité on pris sa défense
(voir par exemple : http://www.gotw.ca/publications/mill19.htm), et je
crois qu'il avait même été question de la "précater" (l'inverse de
deprecated, quoi).



--
Loïc

Avatar
Michel Decima
Loïc Joly wrote:

Parce qu'elle a ce statut dans la norme (ce qui est en fait un
avertissement que la prochaine version de la norme pourrait ne pas la
comporter. C'est peu vraissemblable que ce sera le cas.


Et ce d'autant plus que certains membres du commité on pris sa défense
(voir par exemple : http://www.gotw.ca/publications/mill19.htm), et je
crois qu'il avait même été question de la "précater" (l'inverse de
deprecated, quoi).


Ok, merci a vous deux pour la precision sur la norme, et surtout pour
le lien, ca a l'air d'etre une bonne comparaison de toutes les
possibilites, il faut que je lise plus en detail.