 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Delf Guest
|
Posted: Sat Apr 29, 2006 10:06 pm Post subject: Equivalent StringBuilder |
|
|
Bonsoir,
je cherche un équivalent de StringBuffer/StringBuilder mais en C++.
J'ai une chaîne que je créé par concaténation de nombreux caractères...
pas très performant...
Merci :)
--
Delf
Do not use this email in Cc!
Quand je vais aux chiottes, je prends un manuel CISCO. |
|
| Back to top |
|
 |
Sylvain Guest
|
Posted: Sat Apr 29, 2006 11:06 pm Post subject: Re: Equivalent StringBuilder |
|
|
Delf wrote on 29/04/2006 23:22:
| Quote: | Bonsoir,
je cherche un équivalent de StringBuffer/StringBuilder mais en C++.
tu cherches une implémentation avec d'éventuelles contraintes |
particulières (ascii 8bits et/ou UTFn et/ou ??) ou juste un nom comme
'ostringstream' ?
| Quote: | J'ai une chaîne que je créé par concaténation de nombreux caractères...
pas très performant...
|
tu peux déjà commencer par un type simplissime (sans reallocation, avec
taille fixe figée à la création) comme:
class String {
private:
char* internal;
size_t count, size;
public:
String(size_t max){
internal = new char[size = max + 1];
::memset(internal, 0, size);
count = 0;
}
~String(){
delete [] internal;
}
operator const char* () const {
return internal;
}
friend String& operator << (String& ioStr, char ch){
if (ioStr.count < ioStr.size)
ioStr.internal[ioStr.count++] = ch;
return ioStr;
}
};
Sylvain. |
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Sun Apr 30, 2006 2:06 am Post subject: Re: Equivalent StringBuilder |
|
|
On Sat, 29 Apr 2006 23:22:57 +0200, Delf <no-one (AT) nowhere (DOT) no>:
| Quote: | J'ai une chaîne que je créé par concaténation de nombreux caractères...
pas très performant...
|
Tu veux dire que tu as effectivement vérifié que std::string est trop
lent pour tes besoins ?
Si oui, et si tu as une estimation de la taille finale, tu peux
commencer par essayer en utilisant std::string::reserve(). |
|
| Back to top |
|
 |
Jean-Marc Bourguet Guest
|
|
| Back to top |
|
 |
Delf Guest
|
Posted: Sun Apr 30, 2006 10:06 am Post subject: Re: Equivalent StringBuilder |
|
|
Fabien LE LEZ wrote:
| Quote: | Tu veux dire que tu as effectivement vérifié que std::string est trop
lent pour tes besoins ?
|
Non. Mais si je réalloue à chaque concaténation, je suis persuadé que
c'est pas le mieux à faire.
| Quote: | Si oui, et si tu as une estimation de la taille finale, tu peux
commencer par essayer en utilisant std::string::reserve().
|
J'avais pensé à utiliser reverse() mais je ne peux pas estimer la taille
finale.
--
Delf
Do not use this email in Cc!
L'alcool tue lentement. On s'en fout. On n'est pas pressé. |
|
| Back to top |
|
 |
Delf Guest
|
Posted: Sun Apr 30, 2006 10:06 am Post subject: Re: Equivalent StringBuilder |
|
|
Fabien LE LEZ wrote:
| Quote: | Pour rajouter des caractères, j'ai des doutes. Utiliser directement
std::string::append() n'est-il pas plus efficace ?
|
A vrai dire, je ne sais pas. En Java ou C#, quand je concatène des
caractères, je n'utilise jamais la classe String mais son équivalent.
Après, je n'ai jamais fait de tests de performance, je fais confiance
aux documentations.
--
Delf
Do not use this email in Cc!
Etant philosophe, j'ai un problème pour chaque solution. |
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Sun Apr 30, 2006 10:06 am Post subject: Re: Equivalent StringBuilder |
|
|
On 30 Apr 2006 09:53:45 +0200, Jean-Marc Bourguet <jm (AT) bourguet (DOT) org>:
| Quote: | J'ai une chaîne que je créé par concaténation de nombreux caractères... pas
très performant...
ostringstream ?
|
Pour rajouter des caractères, j'ai des doutes. Utiliser directement
std::string::append() n'est-il pas plus efficace ? |
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Sun Apr 30, 2006 11:06 am Post subject: Re: Equivalent StringBuilder |
|
|
On Sun, 30 Apr 2006 11:53:58 +0200, Delf <no-one (AT) nowhere (DOT) no>:
| Quote: | Tu veux dire que tu as effectivement vérifié que std::string est trop
lent pour tes besoins ?
Non.
|
Dans ce cas, fais-le.
Optimiser au hasard ne donne jamais rien de bon.
| Quote: | Mais si je réalloue à chaque concaténation,
|
Et pourquoi réallouerais-tu à chaque concaténation ?
Note que si tu utilises reserve() à bon escient, tu es assuré de
l'absence de réallocation.
Tu as besoin d'un type "chaîne de caractères". Le type par défaut en
C++ est std::string. C'est donc le premier à essayer.
À la rigueur, si tu n'es pas sûr de toi, tu peux faire un
typedef std::string Chaine;
pour pouvoir facilement changer le type a posteriori.
Crée puis compile le programme, et fais-le tourner.
S'il tourne assez vite, ton boulot est terminé.
S'il est trop lent, il te faut un profiler pour déterminer la cause de
cette lenteur. Elle n'est pas forcément où tu l'attends. |
|
| Back to top |
|
 |
Delf Guest
|
Posted: Sun Apr 30, 2006 11:06 am Post subject: Re: Equivalent StringBuilder |
|
|
Fabien LE LEZ wrote:
| Quote: | Et pourquoi réallouerais-tu à chaque concaténation ?
Note que si tu utilises reserve() à bon escient, tu es assuré de
l'absence de réallocation.
[...]
Crée puis compile le programme, et fais-le tourner.
S'il tourne assez vite, ton boulot est terminé.
[...]
S'il est trop lent, il te faut un profiler pour déterminer la cause de
cette lenteur. Elle n'est pas forcément où tu l'attends.
|
Ce que je vais faire pour l'instant, c'est garder le code actuel, et je
verrai comment tout ça se comporte lors d'une exécution normale.
Pour l'instant, je ne peux pas le faire tourner, il me faut certaines
données en entrée que je n'ai pas.
Merci.
--
Delf
Do not use this email in Cc!
A quoi bon soulever des montagnes quand il est si simple de passer par
dessus ? |
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Sun Apr 30, 2006 11:06 am Post subject: Re: Equivalent StringBuilder |
|
|
Delf wrote:
| Quote: | je cherche un équivalent de StringBuffer/StringBuilder mais en
C++.
J'ai une chaîne que je créé par concaténation de nombreux
caractères... pas très performant...
|
L'idée de base, en C++, c'est que std::string soit assez
performant pour ça. Si ce n'est pas le cas, essaie
std::vector<char>, avec une conversion au moyen de
std::string( v.begin(), v.end() ). Et si tu connais la taille
finale d'avance, n'hésite pas à te servir de
std::vector<>::reserve().
--
James Kanze kanze.james (AT) neuf (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Sun Apr 30, 2006 11:06 am Post subject: Re: Equivalent StringBuilder |
|
|
Jean-Marc Bourguet wrote:
| Quote: | Delf <no-one (AT) nowhere (DOT) no> writes:
je cherche un équivalent de StringBuffer/StringBuilder mais
en C++.
J'ai une chaîne que je créé par concaténation de nombreux
caractères... pas très performant...
ostringstream ?
|
Il a bien dit « pas très performant ». D'après ce que j'ai
entendu dire, ça pourrait s'appliquer encore plus à
ostringstream.
Dans la pratique :
std::vector< char > : garantit les performances des push_back ; il
garantit en plus que reserve ait un effet.
std::string : rien de garantit, et dans la pratique, il y a, ou
il y a bien eu, des implémentations où push_back prend un
temps O(n), où n est la taille de la chaîne (ce qui veut
dire que construire une chaîne de taille n de cette manière
est O(n^2)).
Dans une implémentation qui n'est pas trop mauvaise, reserve
doit avoir un effet (mais la norme permet de le traiter
comme un no-op). En faisant quelque chose du genre :
if ( buffer.size() == buffer.capacity() ) {
buffer.reserve( 2 * buffer.size() ) ;
}
avant chaque push_back, on doit dans la pratique atteindre
quelque chose qui s'approche aux performances de
std::vector< char >.
std::ostringstream : la norme ne dit absolument rien de ses
performances, qui sont souvent assez décévantes.
Personellement, si ce n'est que du caractère par caractère,
j'utiliserais std::string et push_back d'abord. Si ça s'avérait
trop lent, je le remplacerais avec std::vector< char > et
push_back, suivi d'un std::string( v.begin(), v.end() ) pour
convertir le résultat en chaîne.
--
James Kanze kanze.james (AT) neuf (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Sun Apr 30, 2006 11:06 am Post subject: Re: Equivalent StringBuilder |
|
|
On Sun, 30 Apr 2006 11:52:07 +0200, Delf <no-one (AT) nowhere (DOT) no>:
| Quote: | A vrai dire, je ne sais pas. En Java ou C#, quand je concatène des
caractères, je n'utilise jamais la classe String mais
son équivalent.
|
C'est quoi, "son équivalent" ?
| Quote: | Après, je n'ai jamais fait de tests de performance, je fais confiance
aux documentations.
|
Quelles documentations ?
Ça m'étonnerait que l'éditeur d'un compilateur C++ récent claironne
fièrement que son implémentation de std::string est pourrie... |
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Sun Apr 30, 2006 12:06 pm Post subject: Re: Equivalent StringBuilder |
|
|
On Sun, 30 Apr 2006 12:49:56 +0200, James Kanze <kanze.james (AT) neuf (DOT) fr>:
| Quote: | suivi d'un std::string( v.begin(), v.end() ) pour
convertir le résultat en chaîne.
|
Attention, je connais au moins un compilateur[*] (ou plutôt la SL qui
va avec) où ça ne marche pas : si mes souvenirs sont bons, ce con-là
fait un std::string::push_back() par élément
Par contre, std::string (&v[0], v.size()) fonctionne.
[*] Borland C++ 5.02. Mais t'es trop jeune pour l'avoir connu... |
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Sun Apr 30, 2006 9:06 pm Post subject: Re: Equivalent StringBuilder |
|
|
Delf wrote:
| Quote: | Fabien LE LEZ wrote:
Tu veux dire que tu as effectivement vérifié que std::string
est trop lent pour tes besoins ?
Non. Mais si je réalloue à chaque concaténation, je suis
persuadé que c'est pas le mieux à faire.
|
Le fait que string a à la fois une capacité et une taille laisse
penser que l'intention est qu'il n'alloue pas à chaque
concatenation.
| Quote: | Si oui, et si tu as une estimation de la taille finale, tu
peux commencer par essayer en utilisant
std::string::reserve().
J'avais pensé à utiliser reverse() mais je ne peux pas estimer
la taille finale.
|
Tu pourrais toujours t'en servir pour forcer une stratégie de
croissance à ta guise.
--
James Kanze kanze.james (AT) neuf (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Sun Apr 30, 2006 9:06 pm Post subject: Re: Equivalent StringBuilder |
|
|
Delf wrote:
| Quote: | Fabien LE LEZ wrote:
Pour rajouter des caractères, j'ai des doutes. Utiliser
directement std::string::append() n'est-il pas plus efficace
?
A vrai dire, je ne sais pas. En Java ou C#, quand je concatène
des caractères, je n'utilise jamais la classe String mais son
équivalent.
|
La conception de java.lang.String est bien différent de celle de
std::string. En Java, String est immuable -- pour y ajouter un
caractère, il faut faire quelque chose du genre :
s = s + caractère ;
où « s + caractère » est une forme simplifiée d'écrire :
new StringBuffer( s ).append( charactère ).asString() ;
Et oui, pour créer une chaîne caractère par caractère, ça risque
d'être un peu lent. En C++, en revanche, std::string n'est pas
du tout immuable, et il n'y a pas de raison de croire a priori
que « s += caractère » fasse la moindre allocation. (De temps en
temps, il en faudra bien, mais pas à chaque coup.)
| Quote: | Après, je n'ai jamais fait de tests de performance, je fais
confiance aux documentations.
|
Sauf que les documentations ne disent jamais si une telle
fonctionnalité va poser un problème de performance dans ton
application. Il y a des cas (beaucoup même) en Java où
j'écrivais « s = s + caractère ». Et mes applications étaient
assez vites quand même.
--
James Kanze kanze.james (AT) neuf (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|