stream oder +=



  • std::vector<char>



  • @out
    Bist du sicher dass std::string::operator += ähnliche Komplexitätsgarantien gibt wie std::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 wie std::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


  • Mod

    knivil schrieb:

    Bist du sicher dass std::string::operator += ähnliche Komplexitätsgarantien gibt wie std::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 StringBuilder in Gedanken in C++ als std::vector<char> .

    Natürlich darf es auch gerne mal std::string sein, aber nur wenn ich sicher bin dass es OK ist.



  • knivil schrieb:

    Bist du sicher dass std::string::operator += ähnliche Komplexitätsgarantien gibt wie std::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 wenn std::string Speicherplatz 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 quasi

    std::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 vorausgesetzt std::string hat die "push_back" Optimierung nicht... dann ist der "Sonderfall" ja wohl ganz einfach: häng 1 Mio. Wörter zusammen.

    Ob und wieviel std::ostringstream da 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 bei std::string . Weil's halt der klassische Anwendungsfall für nen std::ostringstream ist.

    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.


  • Mod

    hustbaer schrieb:

    @SeppJ
    Also vorausgesetzt std::string hat 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::string hat 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.


Anmelden zum Antworten