Stream extrem langsam?
-
CStoll schrieb:
meinst du das "nur" jetzt ernst? 5 MB sind 5 Millionen Byte (plus ein bisschen), da dauert die Ausgabe doch etwas. beschleunigen könntest du das ein wenig, indem du den Stream selber entscheiden lässt, wann er seine Daten auf die Platte schreiben will (dazu mußt du die ganzen
endlfür die HTML-Ausgabe ersetzen durch'\n')*.* Es geht schneller, einmal 1kB Daten auf Platte zu schreiben als 1024 mal 1 Byte, darum hat der Stream einen Zwischenpuffer, in den er die Daten reinpackt, bis er ein ausreichend großes Paket zusammenbekommen hat.
PS: Was für einen Sinn soll es denn haben, ein Bitmap zu einer riesigen HTML-Tabelle umzuarbeiten? Wenn du Bilder im Netz übertragen willst, solltest du sie auch als Bilder übertragen (zur Not als JPEG oder GIF).
sinn macht es keinen, ich hab nur letztens auf youtube gesehen, wie jemand mit html von hand bilder gemalt hat, und da dachte ich mir, sowas kann man auch automatisieren

naja jedenfalls hat es im nachhinein dann doch nen sinn gehabt, das ist nähmlich ein toller browserbenchmark. Ich habe dadurch rausgefunden, das Opera und der IE tabellen um nen riesigen faktor schneller darstellen können als firefoxedit2: was meinst du mit "ausgabe" ? die 5 mb werden am ende in einem schritt geschrieben, und das dauert auch nur unwesentlich lange. was wirklich dauert ist die eingabe in den pufferstream!
edit3: und das mit dem "nur" meinte ich ernst.. 5 mb sind doch nun wirklich nicht viel... andere programme schaffen es in 20 minuten 5 gigabyte herumzuschieben
-
MFK schrieb:
CStoll schrieb:
beschleunigen könntest du das ein wenig, indem du den Stream selber entscheiden lässt, wann er seine Daten auf die Platte schreiben will
Ich bin mir nicht sicher, ob du gesehen hast, dass er zuerst alles in einen stringstream packt.
Nein, das habe ich wohl übersehen
OK, dann kannst du die Bemerkung mit dem endl vermutlich vergessen, aber dafür hast du ein anderes Problem: Der Stream verwendet selber auch nur string::push_back() bzw. string::append(), um seinen Puffer zu füllen - und dabei muß ständig neuer Speicher angefordert werden, während der String langsam wächst (und jedes Mal werden alle bisherigen Daten umkopiert, wenn das passiert).
-
CStoll schrieb:
MFK schrieb:
CStoll schrieb:
beschleunigen könntest du das ein wenig, indem du den Stream selber entscheiden lässt, wann er seine Daten auf die Platte schreiben will
Ich bin mir nicht sicher, ob du gesehen hast, dass er zuerst alles in einen stringstream packt.
Nein, das habe ich wohl übersehen
OK, dann kannst du die Bemerkung mit dem endl vermutlich vergessen, aber dafür hast du ein anderes Problem: Der Stream verwendet selber auch nur string::push_back() bzw. string::append(), um seinen Puffer zu füllen - und dabei muß ständig neuer Speicher angefordert werden, während der String langsam wächst (und jedes Mal werden alle bisherigen Daten umkopiert, wenn das passiert).hm dann könnte man den benötigten platz vorher berechnen, aber wie kann ich dem stream vorher platz reservieren?
-
mal abgesehen von allem, 30min fpr 5mb ist doch schon bischen arg lange..
-
Könnte man hier nicht mit stringstream::rdbuf::setbuf dem Stringstream gleich so groß machen, dass das seltener passiert?
-
Schreib doch direkt in die Datei
-
Vermutlich gar nicht (außer durch einige üble Hacks, die ich hier nicht einmal erwähnen möchte), weil der Stream dir keinen Direktzugriff auf seinen unterliegenden String genehmigt. Wie ändert sich denn die Laufzeit, wenn du direkt in einen fstream schreibst (natürlich nachdem du die unnötigen endl's ausgewechselt hast)?
-
Hast du mal als Gegentest die Ausgabe in den Stream weg gelassen? Also das du zwar weiterhin berechnest aber den Stream weg lässt.
for(int i = 0; i < numLines; i++) { cPer = (100*i)/(numLines); if(cPer > lastPer) { lastPer = cPer; cout << cPer << "% Done (" << (numCols*i) << " Pixels)" << endl; } // htmlText << "<tr height='1'>" << endl; for(int j = 0; j < numCols; j++) { // htmlText << "<td width='1' height='1' bgcolor='#" << hex << int dummy = (int)pixels[(numCols*i) + j]; } // htmlText << "</tr>" << endl; }Wie ist nun die Performance?
-
CStoll schrieb:
Vermutlich gar nicht (außer durch einige üble Hacks, die ich hier nicht einmal erwähnen möchte), weil der Stream dir keinen Direktzugriff auf seinen unterliegenden String genehmigt. Wie ändert sich denn die Laufzeit, wenn du direkt in einen fstream schreibst (natürlich nachdem du die unnötigen endl's ausgewechselt hast)?
teste ich mal aus... dauert n paar minuten
edit:
so... hier die ergebnisse:Alte methode:
Finished and saved to file!
19200 pixels written in 112692 millisecondsnur ein dummy :
Finished and saved to file!
19200 pixels written in 61 millisecondsund wenn ich direkt in die datei schreibe:
Finished and saved to file!
19200 pixels written in 641 milliseconds!!
also direkt in die datei schreiben

thx
edit2: na heiss:
Finished and saved to file!
480000 pixels written in 12550 milliseconds480.000 pixel in 12 sekunden, statt 19.200 pixel in 2 minuten...die stream funktion sollte vielleicht n bissel überarbeitet werden (man könnte ja vielleicht versuchen den benötigten speicher vorherzusehen, statt linear immer gleich viel dranzuhängen)
-
Aus diesem Grund wäre es vielleicht doch besser direkt rauszuschreiben. Dann werden die Sachen einfach auf die Platte geschoben und nicht noch umkopiert.
edit: argh, kommt davon, wenn man zwischendrin was anderes macht

-
pixartist schrieb:
naja jedenfalls hat es im nachhinein dann doch nen sinn gehabt, das ist nähmlich ein toller browserbenchmark. Ich habe dadurch rausgefunden, das Opera und der IE tabellen um nen riesigen faktor schneller darstellen können als firefox
<img src='bg.gif'>du packst in jede deiner tabellenzellen ein bild, wahrscheinlich 1x1 pixel groß? das macht firefox langsam, nicht die tabelle. schreib wenigstens die größe des bildes mit ins tag.
-
pixartist schrieb:
480.000 pixel in 12 sekunden, statt 19.200 pixel in 2 minuten...die stream funktion sollte vielleicht n bissel überarbeitet werden (man könnte ja vielleicht versuchen den benötigten speicher vorherzusehen, statt linear immer gleich viel dranzuhängen)
Erstens: string's vergrößern ihren Speicher nicht linear, sondern idR exponentiell.
Zweitens: Woher soll der Stream ganz am Anfang wissen, wieviele Daten er letztendlich benötigen wird?
Drittens: Der Haupt-Engpass bei deinem Test wird wohl der Heap-Manager gewesen sein - 5MB kann der auch nicht so einfach aus dem Ärmel schütteln (und höchstwahrscheinlich kommst du da in Größenordnungen, wo Windows anfängt über Swapping nachzudenken).
-
Eine andere möglichkeit wären vielleicht auch die (deprecated) strstreams. Da muß man den Buffer selbst managen und in Deinem Fall lässt sich die benötigte Größe ja recht gut vorher abschätzen. Das könnte auch ordentlich speed bringen. Am Schluß wird dann ein einziges mal rausgeschrieben.
-
Welche Stdlib-Implementierung verwendest du? Ist es die von Dinkumware?