Resourcenproblem mit std::stringstream



  • pro_develop schrieb:

    @pumuckl:

    okay ... und mit welchen tools bzw. librarys könnte ich das noch besser untersuchen ?

    Die Tools heißen allgemein Profiler, mit denen kannst du Performance- und Ressourcenverbrauch untersuchen.



  • Artchi schrieb:

    pro_develop! Warum benutzt du denn stringstream ? Wenn du problemlos string nutzen kannst, war stringstream eh die falsche Klasse. Denn normalerweise erfüllen beide Klassen unterschiedliche Zwecke.

    siehe Anfangsproblematik ... ich generiere einen Stream mit der zur Verfügung stehenden Formatierung der Daten und muss dann einer Bibliotheksmethode eine Referenz auf std::string übergeben ...



  • pro_develop schrieb:

    siehe Anfangsproblematik ... ich generiere einen Stream mit der zur Verfügung stehenden Formatierung der Daten und muss dann einer Bibliotheksmethode eine Referenz auf std::string übergeben ...

    Aha! Also kannst du doch nichts mit string anfangen. Denn zum Formatieren ist string nicht fähig. D.h. du mußt mit einer nicht- string -Klasse erstmal eine Zeichenkette formatieren, richtig? Egal wie du das anstellst, du wirst string dafür nicht nutzen können.

    Wie willst du also eine Kopie der formatierten Zeichnkette vermeiden? 😃

    Dir bleibt nichts anderes übrigig, als einen eigenen stringstream zu implementieren oder Algorithmen (freie Funktionen), und bei der Übergabe des Strings an den Ctor die Endgültige Größe zu kennen:

    // PSEUDO CODE!
    
    class stringstream
    {
        std::string &sref; // entscheidender Punkt!
    
    public:
        stringstream(std::string &s) : sref(s) {}
    
    // I/O Operatoren........
    };
    
    // ==========================================
    
    int main()
    {
     std::string s(10000, ' '); // String wird 10.000 Zeichen enthalten
    
     stringstream st(s);
     // irgendwas formatieren...
    
     foo(s);  // fremde Funktion, die einen std::string fordert
    }
    

    Dann würden die Operatoren direkt den referenzierten String manipulieren. Und damit sich das ganze auch rentiert, darf in dem oberen Beispiel der String keine 10.000 Zeichen übersteigen, weil sonst schon eine Kopieraktion im string nötig wäre - die du eigentlich vermeiden willst.

    Auch dürfen die Operatoren nur Zeichen im String manipulieren, aber keine zus. hinzufügen, da sonst eine Kopieraktion in string droht.

    Also ohne Profiler würde ich da keinen Finger für krumm machen... weil sonst ist alles für die Katz gewesen. 🙄



  • @Artchi:

    ich hab doch nicht gesagt, dass ich etwas mit sring formatieren will ... ??? *verzweifel*

    siehe Anfangsproblematik ... ich generiere einen Stream mit der zur Verfügung stehenden Formatierung der Daten und muss dann einer Bibliotheksmethode eine Referenz auf std::string übergeben ...

    ich schreibe in einer Schleife in den stringstream ...

    hugo << hex << var_a << endl;
    

    und damit wächst der in std::stringstream enthaltene std::string kontinuierlich an bis er z.B. 100 MB groß ist ...

    und dann möchte ich eine Library verwenden, die den std::string parst, ohne beim erzeugen des std::string Objekts eine Speicherbelgung von 200 MB zu benötigen ...



  • Also du moechtest 100 MB an Text parsen ... wieviel Buecher das wohl sind? Kann das Parsen nicht in kleine Teile zerlegt werden?



  • klingt ja stark als ob der op strstream suchen würde...



  • Shade Of Mine schrieb:

    klingt ja stark als ob der op strstream suchen würde...

    strstream ist meines Wissens deprecated. Also nicht gerade zukunftssicher. Aber selbst wenn, hilft das dem OP auch nicht weiter.



  • pro_develop schrieb:

    @Artchi:

    ich hab doch nicht gesagt, dass ich etwas mit sring formatieren will ... ??? *verzweifel*

    Ist mir schon klar. Du hast nur nicht verstanden, wohin ich dich führen will. (sie unten letzter Absatz) Anscheinend hast du dich da in etwas verbissen, und du bist hier der einzige ... sonst wären wir nicht auf Seite 3.

    pro_develop schrieb:

    ich schreibe in einer Schleife in den stringstream ...

    hugo << hex << var_a << endl;
    

    und damit wächst der in std::stringstream enthaltene std::string kontinuierlich an bis er z.B. 100 MB groß ist ...

    Wer sagt denn das im stringstream ein string drin ist? 🙄 Das ist doch ein Implementierungsdetail, das dir am A**** vorbei gehen sollte! Denk doch einfach erstmal abstrakt. Ist zwar erstmal schwer zu lernen, aber das muß man auch lernen - abstrakt denken.

    pro_develop schrieb:

    und dann möchte ich eine Library verwenden, die den std::string parst, ohne beim erzeugen des std::string Objekts eine Speicherbelgung von 200 MB zu benötigen ...

    Wer garantiert dir das 200 MB belegt werden? Kann garnicht gehen.
    1. weil ein stringstream nicht mit einem string implementiert sein muß.
    2. wenn es mit einem string implementiert sein sollte, könnte string so implementiert sein eine interne Refernzzählung zu betreiben. So das zwar ein zweites string-Objekt da wäre, aber das zweite string-Objekt intern auf die Zeichenkette vom ersten string-Objekt verweist!
    3. du könntest auch den stringstream in einen Scope einschränken, so das (falls wirklich der Fall) die 200 MB nur kurzzeitig belegt sind. Beispiel:

    const std::string format()
    {
         stringstream s;
         // formatierung
         return s.str(); // RVO
    }
    
    void foo()
    {
        libfunction(format());
    }
    

    Aber ganz ehrlich? Ich weiß nicht was du willst? Weil einerseits mit stringstream formatieren wollen, andererseits einen string übergeben wollen... ist paradox, keine Datenkopie zu haben.



  • Artchi schrieb:

    Shade Of Mine schrieb:

    klingt ja stark als ob der op strstream suchen würde...

    strstream ist meines Wissens deprecated. Also nicht gerade zukunftssicher. Aber selbst wenn, hilft das dem OP auch nicht weiter.

    deprecated, ja.
    aber warum hilft das denn nicht?

    strstream erlaubt die gewünschten formatierungen auf einem rohen puffer zu machen. somit habe ich die daten in dem stream und in dem "string" gleichzeitig ohne kopieren zu müssen...



  • Shade Of Mine schrieb:

    Artchi schrieb:

    Shade Of Mine schrieb:

    klingt ja stark als ob der op strstream suchen würde...

    strstream ist meines Wissens deprecated. Also nicht gerade zukunftssicher. Aber selbst wenn, hilft das dem OP auch nicht weiter.

    deprecated, ja.
    aber warum hilft das denn nicht?

    strstream erlaubt die gewünschten formatierungen auf einem rohen puffer zu machen. somit habe ich die daten in dem stream und in dem "string" gleichzeitig ohne kopieren zu müssen...

    Aber die Library-Funktion, die der OP aufrufen will, will ein std::string-Objekt. D.h. er müsste diesen rohen Daten dem Ctor des string-Objekts übergeben... und dieses macht doch auch eine Kopie von diesen Rohdaten?!

    Ich habe übrigens gesehen, das man mit rdbuf() auch auf den Stringbuffer im Stringstream zugreifen kann. 😃 Aber ist halt auch kein string-Objekt... auch hier ist eine Kopie nötig.

    Er wird um das Kopieren nicht rum kommen.



  • Artchi schrieb:

    Aber die Library-Funktion, die der OP aufrufen will, will ein std::string-Objekt. D.h. er müsste diesen rohen Daten dem Ctor des string-Objekts übergeben... und dieses macht doch auch eine Kopie von diesen Rohdaten?!

    Man kann dem streambuf von strstream einen bereits erstellten char-buffer zum draufrumschreiben übergeben. Also z.B. einen string nehmen, ihn genügend resizen, mittels <insert some evil nonstandard hack here> auf den drunterliegenden (nonconst!) char-array zugreifen und den an den strstream übergeben, damit der drauf rumschreibt.
    Das wäre dann viel böse Magie um ein Speicherproblem zu behacken, von dem immernoch nicht sichergestellt ist ob es auch wirklich das Speicherproblem ist, wenn es denn überhaupt ein nennenswertes Problem dabei gibt.



  • OK, du meinst diese Funktion?
    http://www.cplusplus.com/reference/iostream/stringbuf/setbuf/

    Gut, dann hat er jetzt seinem Stream diesen vorbereiteten Puffer übergeben. Wie geht er jetzt weiter vor, um eine Kopie (bei der Erstellung eines std::string-Objektes) zu vermeiden?



  • drückt ihm doch erstmal nen profiler rein.... bevor ihr hier so nen wind macht.



  • Artchi schrieb:

    OK, du meinst diese Funktion?
    http://www.cplusplus.com/reference/iostream/stringbuf/setbuf/

    Nein. Ich rede von strstream, nicht von stringstreams stringbuf. Dem Ctor von strstream kann ein char-array zum beackern übergeben werden - er erstellt sich dann kein eigenes.

    It0101 schrieb:

    drückt ihm doch erstmal nen profiler rein.... bevor ihr hier so nen wind macht.

    Ist doch schon geschehen. Mehr als zigmal drauf hinweisen dass das Problem vielleicht garkeines ist können wir kaum 😉



  • pumuckl schrieb:

    It0101 schrieb:

    drückt ihm doch erstmal nen profiler rein.... bevor ihr hier so nen wind macht.

    Ist doch schon geschehen. Mehr als zigmal drauf hinweisen dass das Problem vielleicht garkeines ist können wir kaum 😉

    Vll? Oo
    Er macht sich sorgen, weil er 1MB kopieren muss...
    Ich weiß ja nicht, wie oft er das tut, aber wenn man nen paar 100Gbps kopieren kann, dann sollte 1MB nicht mal spürbar sein... Und wenns um eine Million Zeichen geht, gibts mit Sicherheit nen "richtigen" Flaschenhals^^

    bb



  • Alternativ kann der std::string auch sukzessiv aufgebaut werden, in dem nur Teile von std::stringstream eingelesen und an std::string angehangen werden. Das loest nicht dein Kopierproblem, doch der zusaetzliche Speicher wird auf die Groesse des auf einmal einzulesenden Blocks reduziert (theoretisch).



  • Danke für die vielen Tipps und Vorschläge 🙂

    @Nexus: Du bist der Beste 😉

    heute mittag stand mir wohl jemand auf der Leitung ... jetzt hab ich verstanden, was du gemeint hattest mit dem Vorschlag über append() den std::string aufzubauen ... ich war irgendwie an der Stelle, wenn ich den Stream schon erstellt habe ... klar, wenn ich einen Stream lokal immer wieder erstelle und dann meine Daten damit formatiere, kann ich den String langsam mit append()zusammensetzen ... das ist die Lösung !

    Ich bin aber trotzdem der Meinung, dass die Bibliothek an dieser Stelle keiner klaren Linie folgt, wenn in strstream der Speicher zugreifbar war, in der stringstream Template Klasse jedoch nicht mehr ... fstream arbeitet ja auch nicht auf einer temp. Kopie der Datei, damit die Daten nicht von einer anderen Stelle aus verändert werden können ...

    Werde der WG21 mal eine Mail schreiben ...



  • jetzt hab ich verstanden, was du gemeint hattest mit dem Vorschlag über append()

    Oh, der Vorschlag kam schon ... und warum hat das dann 4 Seiten gebraucht, bis es durchsickert ... *kopfschuettel*



  • pro_develop schrieb:

    @Nexus: Du bist der Beste 😉

    Hehe, vielen Dank. Schön, dass dir mein Vorschlag geholfen hat! 🙂

    @ Premature-Optimization-Fanatiker: 😉
    Es ist im Allgemeinen sicher nicht schlecht, nachzumessen, statt seine Urteile auf Vermutungen zu basieren. Wenn es aber offensichtlich ist, dass eine Möglichkeit, die weder viel Mehraufwand noch sonstige Probleme (schlechtere Wartbarkeit, hässliches Design oder Ähnliches) mit sich bringt, von der Performance her günstiger ist, dann sollte es doch gerechtfertigt sein, diese zu nutzen.


Anmelden zum Antworten