stream oder +=
-
was ist besser:
while(lange) { ss << ein_char; } str = ss.str();oder
while(lange) { str += ein_char; }warum?
-
Also wer einen std::string mittels ostringstream zusammensetzt... bei dem läuft was schief. ostringstream wird schon oft genug missbraucht, wir wollen ihn jetzt nicht auch noch für sowas missbrauchen... Ich denke die Anwort ist eindeutig.
-
Ein std::string ist ein Spezialist für die Arbeit mit Zeichenketten im Speicher. (Also auch das anhängen)
Die Streams hingegen sind generalisiert und bieten theoretischen Support alle Eingabedaten per Brieftaube nach Südafrika zu senden. Wer ist jetzt wohl besser dafür geeignet?
-
std::vector<char>
-
@out
Bist du sicher dassstd::string::operator +=ähnliche Komplexitätsgarantien gibt wiestd::vector::push_back?
Ich bin mir nämlich fast sicher dass es nicht so ist.D.h. die
std::string::operator +=Variante könnte im schlimmsten Fall für jedes einzelne+=eine Reallocation machen.---
Wenn man die finale Länge des Strings vorab kennt ist es kein Problem. In dem Fall einfach vorher
str.reserve()machen und dann mit+=anhängen.Ohne
str.reserve()finde ich deine Aussage aber etwas gewagt.In den meisten Fällen wird es egal sein, aber dort wo es nicht egal ist würde ich schon wissen wollen was da genau passiert.
-
Bist du sicher dass
std::string::operator +=ähnliche Komplexitätsgarantien gibt wiestd::vector::push_back?
Ich bin mir nämlich fast sicher dass es nicht so ist.cppreference.com sagt: constant. Es waere auch grob fahrlaessig, wenn es nicht die gleiche Komplexitaet wie push_back hat.
-
hustbaer schrieb:
...
Naja, die Frage war, was ist besser? Auf eine allgemeine Frage kannst auch nur eine allgemeine Antwort geben. Und im Allgemeinen kommst du doch sicher nicht auf die Idee, ostringstream zu verwenden. Intuitiv denkst du an push_back/reserve/+=. Erst wenn du einen ganz speziellen Fall hast, denkst du vielleicht weiter. :p
-
knivil schrieb:
Bist du sicher dass
std::string::operator +=ähnliche Komplexitätsgarantien gibt wiestd::vector::push_back?
Ich bin mir nämlich fast sicher dass es nicht so ist.cppreference.com sagt: constant. Es waere auch grob fahrlaessig, wenn es nicht die gleiche Komplexitaet wie push_back hat.
Der Standard sagt aber tatsächlich nichts darüber.
(Das ändert natürlich nichts daran, dass die zweite Variante trotzdem weit besser ist, außer in ganz speziellen Spezialfällen, die hustbaer konstruieren könnte)
-
out schrieb:
hustbaer schrieb:
...
Naja, die Frage war, was ist besser? Auf eine allgemeine Frage kannst auch nur eine allgemeine Antwort geben. Und im Allgemeinen kommst du doch sicher nicht auf die Idee, ostringstream zu verwenden. Intuitiv denkst du an push_back/reserve/+=. Erst wenn du einen ganz speziellen Fall hast, denkst du vielleicht weiter. :p
Intuitiv übersetze ich den Begriff
StringBuilderin Gedanken in C++ alsstd::vector<char>.Natürlich darf es auch gerne mal
std::stringsein, aber nur wenn ich sicher bin dass es OK ist.
-
knivil schrieb:
Bist du sicher dass
std::string::operator +=ähnliche Komplexitätsgarantien gibt wiestd::vector::push_back?
Ich bin mir nämlich fast sicher dass es nicht so ist.cppreference.com sagt: constant. Es waere auch grob fahrlaessig, wenn es nicht die gleiche Komplexitaet wie push_back hat.
Also ich würde weder das eine noch das andere als grob fahrlaessig bezeichnen.
Ich kenne einige Entwickler die es ziemlich schlimm finden würden wennstd::stringSpeicherplatz verschwendet. Man denke da auch an kleine schwachbrüstige Systeme wie sie im embedded Bereich zu finden sind.Klar, wenn man will dass
size() == capacity()könnte man als Programmierer natürlich "deutlich daraufhinweisen", indem man den String nochmal kopiert nachdem er das letzte mal verändert wurde.
Also quasistd::string(str).swap(str);oder so.
Finde ich aber umständlich, bzw. wird wohl kaum ein Programm machen.
OK, ein denkbarer Mittelweg wäre vielleicht den String nicht immer um 30~100% wachsen zu lassen, sondern um vielleicht 5~10%. Speicherplatzverschwendung bleibt es natürlich trotzdem, aber halt nicht mehr ganz so krass.
-
@SeppJ
Also vorausgesetztstd::stringhat die "push_back" Optimierung nicht... dann ist der "Sonderfall" ja wohl ganz einfach: häng 1 Mio. Wörter zusammen.Ob und wieviel
std::ostringstreamda besser abschneidet weiss ich aber ehrlich gesagt auch nicht. Nur würde ich es mir da eher erwarten dass die Klasse auf "String-Builder" optimiert ist als beistd::string. Weil's halt der klassische Anwendungsfall für nenstd::ostringstreamist.Meine Wahl wäre da wie gesagt (siehe vor-voriger Beitrag) eher
std::vector<char>.
-
hustbaer schrieb:
Meine Wahl wäre da wie gesagt (siehe vor-voriger Beitrag) eher
std::vector<char>.std::deque<char>wäre auch noch ein Versuch wert.
-
hustbaer schrieb:
@SeppJ
Also vorausgesetztstd::stringhat die "push_back" Optimierung nicht... dann ist der "Sonderfall" ja wohl ganz einfach: häng 1 Mio. Wörter zusammen.Aber das wichtige Stichwort ist "vorausgesetzt
std::stringhat die "push_back" Optimierung nicht". Das ist dann nämlich der spezielle Sonderfall.Bei so allgemeinen Fragestellungen wie hier sollte man wohl auf normale Heimcomputer abzielen. Wie es auf embedded Prozessoren, Superrechnern oder in verteilten Rechenprojekten ist, kann man gerne nebenher erwähnen. Aber nicht den Normalfall zum Sonderfall erklären, besonders wenn der Unterschied so groß ist. Die Lösung zwei wird hier auf dem Heimrechner um Größenordnungen schneller sein. Ohne zu testen schätze ich mal mindestens einen Faktor 100.