 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Steffen Conrad Guest
|
Posted: Mon Jun 28, 2004 1:45 pm Post subject: Performance von stringstream |
|
|
Hi,
ich hoffe ich bin hier mit meiner STL-Frage richtig.
Ich möchte in einer Klasse ASCII-Output buffern.
Der gebufferte Output kann schon mal gerne ein paar hundert MB haben.
Dabei frage ich mich, ob das Buffern in einem stringstream gegenüber
eines dynamisch allokierten char-Buffers Performance-Einbußen hat.
Gruss,
Steffen
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Markus Breuer Guest
|
Posted: Mon Jun 28, 2004 9:21 pm Post subject: Re: Performance von stringstream |
|
|
Steffen Conrad wrote:
| Quote: | Hi,
ich hoffe ich bin hier mit meiner STL-Frage richtig.
Ich möchte in einer Klasse ASCII-Output buffern.
Der gebufferte Output kann schon mal gerne ein paar hundert MB haben.
Dabei frage ich mich, ob das Buffern in einem stringstream gegenüber
eines dynamisch allokierten char-Buffers Performance-Einbußen hat.
Warum bufferst du es nicht gleich in einem std::string? Das kommt einem |
dynamisch alloierten char[] am nächsten, oder planst du Formatierungen
bevor du in den Buffer schreibst?
Gruß Markus
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Markus Schaaf Guest
|
Posted: Tue Jun 29, 2004 10:29 am Post subject: Re: Performance von stringstream |
|
|
"Steffen Conrad" <steffen.conrad (AT) gmx (DOT) de> schrieb:
| Quote: | Der gebufferte Output kann schon mal gerne ein paar hundert MB haben.
Dabei frage ich mich, ob das Buffern in einem stringstream gegenüber
eines dynamisch allokierten char-Buffers Performance-Einbußen hat.
|
Kann man so nicht beantworten, weil unklar ist, wie "dynamisch
allokierter char-Buffer" arbeitet. Es hängt letztlich von der
Qualität der Bibliothek ab: Ein Hersteller, der sich wörtlich
an den Standard hält, liefert eine Stringstream-Klasse, die die
schlechtestmögliche Performance aufweist. Bei sinnvoller
Implementierung sollte der Stringstream schneller sein, als ein
naives Char-Array.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Stefan Reuther Guest
|
Posted: Tue Jun 29, 2004 6:10 pm Post subject: Re: Performance von stringstream |
|
|
Steffen Conrad wrote:
| Quote: | Der gebufferte Output kann schon mal gerne ein paar hundert MB haben.
Dabei frage ich mich, ob das Buffern in einem stringstream gegenüber
eines dynamisch allokierten char-Buffers Performance-Einbußen hat.
|
JSA 1.0.
Ich gehe erstmal von strings aus, nicht stringstreams.
Unter der Annahme, dass du die erwartete Größe der Ausgabe schätzen
kannst, mit der Schätzung richtig liegst, und am Anfang 'reserve'
aufrufst, ist der Overhead von std::string gegenüber einem char-Array
nahezu Null.
Falls du einfach nur mit push_back anhängst, wird es jedoch leicht
langsam. In jedem Fall hast du mit einer Stringklasse verloren, die den
Puffer immer um eine konstante Menge vergrößert, durch das ständige
Hinundherkopiere hat dein Programm dann nämlich exponenzielle Laufzeit.
Allerdings selbst, wenn der Puffer immer verdoppelt wird (und das
Programm somit formal lineare Laufzeit hat), werden im letzten
Puffer-Vergrößerungs-Schritt mindestens 50 MB kopiert.
Wen's interessiert: Ich hab hier neulich mit MSVC ein Programm zum
Manipulieren von .hex-Dateien gebastelt, die der Einfachheit halber in
einen std::string decodiert werden. Ich hab noch nicht nachgesehen, wie
MS's std::string implementiert ist, aber das Programm hat für einen
String mit ca. 1 MB über eine Minute gebraucht. Dann ein
'reserve(2*1024*1024)' an strategisch günstiger Stelle geparkt, und nun
läuft das Programm in unter einer Sekunde ab.
So, das Hauptproblem ist nun aber, dass du an diese string-Feinheiten
mit deinem stringstream nicht rankommst. Du kannst also nicht 'mal eben'
auf dem String innerhalb des stringstreams 'reserve' aufrufen. Daher
sind Aussagen über die Performance schwer möglich. Immerhin muss ein
stringstream keine 'insert' oder 'erase'-Operationen unterstützen, also
wäre eine effizientere Repräsentation als 'char-Array' durchaus denkbar.
Eine mögliche Repräsentation wäre z.B., anstelle eines großen Arrays
viele kleine (z.B. 10k je Stück) zu speichern. Beim Vergrößern muss dann
immer nur die Liste mit den Zeigern auf die Arrays manipuliert werden,
es muss nicht mehr der ganze Inhalt hin-und-her kopiert werden.
Ich würde einfach testen, wie gut dein Stringstream performt, und wenn
er es nicht tut, einen eigenen Stream mit einer Repräsentation wie hier
erwähnt implementieren.
Stefan
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Markus Breuer Guest
|
Posted: Tue Jun 29, 2004 8:18 pm Post subject: Re: Performance von stringstream |
|
|
Stefan Reuther wrote:
[...]
Ausgehend von der Annahme, std::string und stringstream werden analog
verwendet, dürfte es keinen signifikanten Unterschied in der Laufzeit
geben. Wird der std::string Stück für Stück erweitert, die Länge ist im
Vorfeld nicht bekannt, hätte der char-Buffer mit realloc sich ähnlich
verhalten. Beim stringstream erwarte ich ein ähnliches Verhalten.
Ich stelle mir nun folgende Frage: wie verhält sich stringstream, wenn
er mit einen std::string initialisiert wird, der bereits mit reserve
vergrößert wurde. Kann ich mit einem Unterschied rechnen?
Gruß Markus
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Helmut Zeisel Guest
|
Posted: Wed Jun 30, 2004 9:22 am Post subject: Re: Performance von stringstream |
|
|
Markus Breuer wrote:
| Quote: | Ich stelle mir nun folgende Frage: wie verhält sich stringstream, wenn
er mit einen std::string initialisiert wird, der bereits mit reserve
vergrößert wurde. Kann ich mit einem Unterschied rechnen?
|
stringstream hat kein reserve; die capacity des strings wird meines
Wissens beim Kopieren des Strings nicht mitkopiert (bzw. macht der
Standard keine Aussage dazu).
Helmut
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Falk Tannhäuser Guest
|
Posted: Wed Jun 30, 2004 9:43 am Post subject: Re: Performance von stringstream |
|
|
Markus Breuer wrote:
| Quote: |
Ich stelle mir nun folgende Frage: wie verhält sich stringstream, wenn
er mit einen std::string initialisiert wird, der bereits mit reserve
vergrößert wurde. Kann ich mit einem Unterschied rechnen?
|
Die Konstruktoren von basic_(i,o)stringstream, welche string akzeptieren,
nehmen ihn stets per Referenz auf const (const basic_string<charT,traits,Allocator>&)
und tun damit nichts weiter, als ihn an den Konstruktor ihres basic_stringbuf-
Members weiterzureichen. Letzterer legt davon eine Kopie in seiner "underlying
character sequence" an (27.7.1.1/3). Es ist nicht spezifiziert, ob selbige
Sequenz in einem basic_string oder anderweitig gespeichert wird. Selbst
wenn es ein string wäre, sagt der Standard nichts weiter über dessen 'capacity()'
nach einem Kopieren aus - die einzige Postkondition der Konstruktoren und
Zuweisungsoperatoren von basic_string ist nur 'capacity() >= size()' (siehe
21.3.1).
Was eventuell gehen könnte, um die gewünschte Optimierung vorzunehmen, wäre,
einen hausgemachten Allokator zu schreiben und damit
template <class charT, class traits = char_traits
class Allocator = allocator<charT> >
class basic_(i,o)stringstream
zu instanzieren - das habe ich aber selbst noch nie probiert; habe auch keine
Ahnung, ob dieser Allokator wirklich intern benutzt wird oder nur zur Instanzierung
der Konstruktoren und 'str()'-Memberfunktionen dient, welche
'basic_string<charT,traits,Allocator>' als Argument ober Rückgabewert haben.
MfG
Falk
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Wed Jun 30, 2004 1:55 pm Post subject: Re: Performance von stringstream |
|
|
Markus Breuer <markus.breuer (AT) gmx (DOT) de> wrote
| Quote: | Stefan Reuther wrote:
[...]
Ausgehend von der Annahme, std::string und stringstream werden analog
verwendet, dürfte es keinen signifikanten Unterschied in der Laufzeit
geben. Wird der std::string Stück für Stück erweitert, die Länge ist
im Vorfeld nicht bekannt, hätte der char-Buffer mit realloc sich
ähnlich verhalten. Beim stringstream erwarte ich ein ähnliches
Verhalten.
Ich stelle mir nun folgende Frage: wie verhält sich stringstream, wenn
er mit einen std::string initialisiert wird, der bereits mit reserve
vergrößert wurde. Kann ich mit einem Unterschied rechnen?
|
Du kannst es ausprobieren. Die Norm sagt relatif wenig darüber, wie die
Implementierung seine Aufgaben erfüllen soll. Das in Stafan Reuthers
Posting Vorgehensweise beim Wachsen eines Strings (konstante Schritte)
ist auch nicht vorgegeben, und stimmt nicht für alle Implementierung.
Wenn Performanz eine Thema ist, bekommst Du einige Garantien mit
std::vector. Ich habe relatif gute Erfahrung mit std::vector<char>,
resize() und dann direkt im Puffer lesen, was mit std::string nicht
möglich ist. Dazu ist eine exponenziele Vergrößerung mit
std::vector<char> garantiert, falls man doch mit push_back arbeiten
will.
Wenn formattiert werden muss, kann man notfalls eine std::ostrstream auf
einem Teil des std::vector<char> anlegen. (Vorsicht dann. Man darf den
vector nicht vergrößern, solange der ostrstream est benutzt.)
--
James Kanze GABI Software http://www.gabi-soft.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
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Stefan Reuther Guest
|
Posted: Wed Jun 30, 2004 6:11 pm Post subject: Re: Performance von stringstream |
|
|
Falk Tannhäuser wrote:
| Quote: | Was eventuell gehen könnte, um die gewünschte Optimierung vorzunehmen, wäre,
einen hausgemachten Allokator zu schreiben und damit
template <class charT, class traits = char_traits
class Allocator = allocator
class basic_(i,o)stringstream
zu instanzieren
|
CMIIW, aber mit dem Allokator hast du doch bestenfalls Einfluss darauf,
wo der String / Stream seinen Speicher her bekommt, nicht, wieviel er
allokiert. Für eine eigene Puffer-Strategie muss es dann schon ein
eigener streambuffer sein.
Stefan
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Steffen Conrad Guest
|
Posted: Mon Jul 05, 2004 2:28 pm Post subject: Re: Performance von stringstream |
|
|
Steffen Conrad wrote:
| Quote: | Hi,
ich hoffe ich bin hier mit meiner STL-Frage richtig.
Ich möchte in einer Klasse ASCII-Output buffern.
Der gebufferte Output kann schon mal gerne ein paar hundert MB haben.
Dabei frage ich mich, ob das Buffern in einem stringstream gegenüber
eines dynamisch allokierten char-Buffers Performance-Einbußen hat.
Gruss,
Steffen
|
Hi all,
erstmal vielen Dank für die vielen Antworten.
Als wir uns nochmal darüber Gedanken gemacht haben, sind natürlich noch
ein paar weitere Aspekte zu Tage gekommen.
Der Buffer soll im Endeffekt für viele Schreiboption von jeweils wenigen
Byte geeignet sein, kann ber unter Umständen relativ grosse Datenmengen
halten müssen. Da wir in der Vergangenheit beim ursprünglichen Tool (wir
arbeiten am Redesign) Probleme mit den Prozess-Limits bekamen, werden
wir wohl einen Buffer mit relativ großer Blockgrösse (so 10-20 MB)
benutzen und bei Bedarf bis auf 100 MB vergrössern. Sollte dies nicht
ausreichen, muss halt in (eine/mehrere) temporäre Datei(en) ausgelagert
werden.
Den Buffer werde ich wohl mit char * machen, da für mich diesbezüglich
Klarhiet herrscht, was an Aktionen läuft und keine grosse Funktionalität
bezüglich Formatierungen/Suche etc. benötigt wird.
Gruss,
Steffen
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Werner Jakobi Guest
|
Posted: Tue Jul 06, 2004 6:33 pm Post subject: Re: Performance von stringstream |
|
|
Steffen Conrad <steffen.conrad (AT) gmx (DOT) de> posted:
| Quote: | Den Buffer werde ich wohl mit char * machen, da für mich
diesbezüglich Klarhiet herrscht, was an Aktionen läuft und keine
grosse Funktionalität bezüglich Formatierungen/Suche etc. benötigt
wird.
|
Das würde ich nicht machen. Nimm irgendeinen Container aus der STL, im
Zweifelsfall std::string. Das bisschen Code, das dafür dazugeladen wird,
wird dich nicht umbringen.
Du hast damit aber einen dynamischen Puffer, der entsprechend deinen
Bedürfnissen automatisch wächst und per Anweisung auch wieder auf
vernünftiges Maß reduziert werden kann.
Ganz abgesehen davon sind die Methoden der STL vermutlich wesentlich
schneller als alles, was du mit deinem verkappten C produzieren kannst.
Gruss, Werner
--
Morver, der Rollstuhl fuer kranke Windows-Newsreader und fuer OE.
Aktuelle Version 1.0.305: http://www.morver.de/
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Martin Aupperle Guest
|
Posted: Sun Jul 11, 2004 10:30 am Post subject: Re: Performance von stringstream |
|
|
On Mon, 28 Jun 2004 23:21:20 +0200, Markus Breuer
<markus.breuer (AT) gmx (DOT) de> wrote:
| Quote: |
Der gebufferte Output kann schon mal gerne ein paar hundert MB haben.
Dabei frage ich mich, ob das Buffern in einem stringstream gegenüber
eines dynamisch allokierten char-Buffers Performance-Einbußen hat.
Warum bufferst du es nicht gleich in einem std::string? Das kommt einem
dynamisch alloierten char[] am nächsten, oder planst du Formatierungen
bevor du in den Buffer schreibst?
bei Allokationen dieser Größenordnungen ist einiges zu beachten. IMHO |
ist die Allokationsstrategie bei std::string häufig so, dass der
Speicher immer verdoppelt wird, wenn ein Überlauf auftritt. Dies kann
hier zu Problemen führen.
Die Implementierung eines geeigneten angepassten Allokators ist
möglich, aber gegenüber einer eigenen streambuf-Klasse die schlechtere
Lösung.
Ich kenne das genaue Problem nicht, aber die Lösung mit iostreams
scheint mir angemessener.
-
------------------------------------------------
Martin Aupperle
Die Kunst der Programmierung mit C++
www.PrimaProgramm.de
------------------------------------------------
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| 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
|
|