Ich habe ein kleines C-Programm zur Berechnung von Hashes (für Hashtabellen). Der Code sieht ziemlich sauber aus, hoffe ich, aber es gibt etwas, das damit nicht zusammenhängt und mich stört.
Ich kann problemlos etwa eine Million Hashes in etwa 0,2-0,3 Sekunden erzeugen (gemessen mit /usr/bin/time). Wenn ich sie jedoch in der for-Schleife mit printf() ausdrucke, verlangsamt sich das Programm auf etwa 5 Sekunden.
- Warum ist das so?
- Wie kann man es schneller machen? mmapp()ing stdout vielleicht?
- Wie ist stdlibc in dieser Hinsicht konzipiert, und wie kann sie verbessert werden?
- Wie könnte der Kernel dies besser unterstützen? Wie müsste er modifiziert werden, damit der Durchsatz bei lokalen "Dateien" (Sockets, Pipes usw.) WIRKLICH schnell wird?
Ich freue mich auf interessante und ausführliche Antworten. Danke!
PS: Dies ist für ein Compilerbau-Toolset, also scheuen Sie sich nicht, ins Detail zu gehen. Das hat zwar nichts mit dem eigentlichen Problem zu tun, aber ich wollte nur darauf hinweisen, dass mich Details interessieren.
Nachtrag
Ich bin auf der Suche nach mehr programmatischen Ansätzen für Lösungen und Erklärungen. Piping erfüllt zwar die Aufgabe, aber ich habe keine Kontrolle darüber, was der "Benutzer" tut.
Natürlich führe ich gerade einen Test durch, der von "normalen Benutzern" nicht durchgeführt werden würde. ABER das ändert nichts an der Tatsache, dass ein einfaches printf() einen Prozess verlangsamt, und das ist das Problem, für das ich versuche, eine optimale programmatische Lösung zu finden.
Addendum - Erstaunliche Ergebnisse
Die Referenzzeit ist für einfache printf()-Aufrufe innerhalb eines TTY und dauert etwa 4 Minuten 20 Sekunden.
Das Testen unter einem /dev/pts (z.B. Konsole) beschleunigt die Ausgabe auf etwa 5 Sekunden.
Es dauert ungefähr gleich lange, wenn ich setbuffer() in meinem Testcode für eine Größe von 16384 verwende, und fast genauso lange für 8192: ungefähr 6 Sekunden.
setbuffer() hat offenbar keine Auswirkung bei der Benutzung: es dauert gleich lang (auf einem TTY etwa 4 Minuten, auf einem PTS etwa 5 Sekunden).
Das Erstaunliche dabei ist wenn ich den Test auf TTY1 starte und dann zu einem anderen TTY wechseln dauert es genauso lange wie bei einem PTS: etwa 5 Sekunden.
Schlussfolgerung : Der Kernel macht etwas, das mit Zugänglichkeit und Benutzerfreundlichkeit zu tun hat. HUH!
Normalerweise sollte es gleich langsam sein, egal ob Sie das TTY anstarren, während es aktiv ist, oder ob Sie zu einem anderen TTY wechseln.
Lektion : Wechseln Sie bei ausgabeintensiven Programmen auf einen anderen TTY!