stdout burst - wir schaufeln die konsole voll

Traveller

Mitglied
Hallo zusammen.

So ein wenig optimieren zum Wochenende ohne Sinn und Verstand beschreibt es ganz gut. Mein Problem ist völlig realitätsfern, musste aber mal sein nach den vielen faulen Javabohnen im Kaffee und auf den Servern diese Woche.
Zum Thema: Ich hab unter Win XP x32 (in C::B) mit VC 2010 ein mehr als triviales Programm geschrieben, das mir einfach alle uints auf die konsole ausgibt. Gut 4 Milliarden Zahlen auf die Konsole schieben, ich dachte in 5 min. ist das machbar. Mit dem primitiven Ansatz ist es das nicht, es dauert ewig. Der Flaschenhals ist scheinbar die Ausgabe in der Konsole des OS, ich kann locker nebenbei Berechnungen ausführen lassen ohne merklichen Performanceverlust bei der Ausgabe. Puffern, formatieren, umkopieren könnte also evtl. nicht schaden.
Und jetzt kommts ... wie optimiert man den Zeichendurchsatz auf stdout?

Code:
#include <iostream>
#include <limits>

using namespace std;

int main()
{
    unsigned int i = 0;
    unsigned int j = numeric_limits<int>::max();

    for (; i < j; i++)
    {
        cout << i << endl;
    }

    return 0;
}

Die ints formatiert in einen String gepackt, mit ein paar kB gepuffert und ostream::write wäre mein nächster Ansatz. Stringstreams sehen auch ganz gut aus. Wird morgen alles mal angetestet.

Aber die Ausgabe muss doch schneller gehen, ich bekomme mit dem primitiven Ansatz gerade mal 5.000 Zeilen pro Sekunde auf die Konsole (Phenom 4x 2.3Ghz). Macht euch bitte mal den Spaß, das Prog anzuschauen und / oder zu optimieren. Es reicht, dass es auf einem Kern läuft, die ausgabe sollte aber nicht ruckeln, sie muss nahezu flüssig auf der konsole laufen. Preise und sonstige awards gibt es leider nicht, mein C::B zeigt die Laufzeit an, ich teste jeden SC und nächsten Freitag werte ich alles aus. Bei mir läuft die Ausgabe elendig lang > 1h.

Viel Spaß, Traveller.
 
Zuletzt bearbeitet:
Hi.

Die iostreams stehen nicht gerade im Ruf sehr schnell zu sein. Zudem ist I/O ziemlich das Langsamte was man im Computer anstellen kann.

Außerdem machst du jedesmal einen Flush (durch das endl).

Es kann auch helfen den Streampuffer zu vergrößern.

Letztendlich ist es allerdings am schnellsten, möglichst keine IOStreams und keine Formatierungen zu verwenden:
C++:
char buf[20];
puts(itoa(i, buf, 10));
Allerdings ist der Flaschenhals nicht die Ausgabe im Programm, sondern die Darstellung des Konsoleninhalts der von Betriebssystemroutinen durchgeführt wird.

Gruß
 
Zuletzt bearbeitet:
Danke deepthroat,

wie gesagt, mein erster Ansatz war sehr Primitiv. Mal sehen, mit welchem deiner Tips das meiste herauszuholen ist. Nicht flushen, streambuffer größer machen, C I/O verwenden ist auf die schnelle testbar, Betriebssystem puh ... ich hab das alte XP x86 und ein x64 Ubuntu. Mir ist leider kein BS bekannt, das auf IO optimiert ist. Evtl. etwas im Echtzeitbereich, das ist aber nur Spekulation.

Gruß, Traveller


Nachtrag:
1. Das endl durch '\n' ersetzen bringt nichts.
2. Streambuffer vergrößern - wie geht das?
3. Die stdio statt iostream verwenden macht die Ausgabe bei mir um den Faktor 6 schneller.
Sieht so aus als hätten wir vorerst einen Gewinner.

ich seh es als erledigt an, der tip von deepthroath, die c i/o zu verwenden war wunderbar.
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück