2009-06-26 19 views
2

Zuweisen einer QTextStream zu einer QFile und lesen Zeile für Zeile ist einfach und funktioniert gut, aber ich frage mich, ob die Leistung kann durch Speichern der Datei im Speicher und erhöht werden dann wird es Zeile für Zeile verarbeitet.Lesen von einer Datei nicht Zeile für Zeile

Mit FileMon von sysinternals, habe ich festgestellt, dass die Datei in Blöcken von 16KB gelesen wird und da die Dateien, die ich verarbeiten muss, nicht so groß sind (~ 2MB, aber viele!), Würde sie in den Speicher geladen werden eine nette Sache, um es zu versuchen.

Irgendwelche Ideen wie kann ich das tun? QFile ist vererbt von QIODevice, die mir ReadAll() es in QByteArray ermöglicht, aber wie dann vorzugehen und in Zeilen zu teilen?

Antwort

4

QTextStream hat eine ReadAll Funktion:

http://doc.qt.io/qt-4.8/qtextstream.html#readAll

Sicher, das ist alles, was Sie brauchen?

Oder Sie könnten alle in die QByteArray lesen und QTextStream kann dies als eine Eingabe anstelle einer QFile nehmen.

+1

Danke! Ich wusste nicht, QTextStream kann QByteArray nehmen. Das löst es total. – MadH

1

Solange Sie die Datei nicht jedes Mal öffnen und schließen, wenn Sie eine einzelne Zeile lesen, sollte es keinen Leistungsunterschied zwischen dem Lesen der gesamten Datei oder der Verarbeitung während des Lesens geben (außer der Verarbeitungsteil) schneller, wenn Sie mit der gesamten Datei arbeiten müssen). Wenn Sie darüber nachdenken, machen beide Wege das gleiche (einmal die gesamte Datei lesen).

2

Seien Sie vorsichtig. Es gibt viele Effekte zu beachten.

Für die betreffende String-Verarbeitung (oder was auch immer Sie mit der Datei machen) gibt es wahrscheinlich keinen Leistungsunterschied zwischen dem Speichern aus einer Datei zeilenweise, vorausgesetzt, dass die Dateipufferung sinnvoll ist.

Wenn Sie Ihr Betriebssystem aufrufen, um ein Low-Level-Lesen durchzuführen, ist es sehr teuer. Deshalb haben wir I/O gepuffert. Bei kleinen E/A-Größen dominiert der Overhead des Anrufs. So ist das Lesen von 64 Bytes wahrscheinlich 1/4 so effizient wie das Lesen von 256 Bytes gleichzeitig. (Und ich spreche von read() hier, nicht fgets() oder fread() beide gepuffert sind.)

Zu einem bestimmten Zeitpunkt beginnt die Zeit für die physische I/O beginnt zu dominieren, und wenn die Leistung steigt nicht viel für einen größeren Puffer haben Sie Ihre Puffergröße gefunden. Sehr alter Datenpunkt: 7MHz Amiga 500, 100MB SCSI-Festplatte (A590 + Quantum): Meine I/O-Performance hat mit einer 256KB-Puffergröße wirklich nur das Maximum erreicht. Verglichen mit dem Prozessor war diese Festplatte SCHNELL !!! (Der Computer hatte nur 3 MB RAM. 256 KB ist ein großer Puffer!)

Allerdings können Sie zu viel von einer guten Sache haben. Sobald sich Ihre Datei im Speicher befindet, kann das Betriebssystem diese Datei nach Belieben auf die Festplatte zurücksenden. Und wenn dies der Fall ist, haben Sie den Vorteil der Pufferung verloren. Wenn Sie Ihre Puffer zu groß machen, kann dies unter bestimmten Belastungssituationen passieren und Ihre Leistung geht auf die Toilette. Berücksichtigen Sie daher Ihre Laufzeitumgebung sorgfältig und begrenzen Sie bei Bedarf den Speicherbedarf.

Eine Alternative ist die Verwendung von mmap(), um die Datei in den Speicher abzulegen. Jetzt wird das OS Ihre Datei nicht mehr pagen - es wird einfach nicht eingefügt, oder wenn es Speicher benötigt, wird es alle Teile der Datei, die im Core zwischengespeichert sind, verwerfen. Aber es muss nichts zum Auslagern von Speicherplatz geschrieben werden - es ist die Datei verfügbar. Ich bin mir nicht sicher, ob dies zu einer besseren Leistung führen würde, da es immer noch besser ist, I/O in großen Blöcken auszuführen, und virtueller Speicher neigt dazu, Dinge in seitengroßen Blöcken zu verschieben.Einige Speichermanager können eine anständige Aufgabe ausführen, indem sie Seiten in Blöcken verschieben, um die E/A-Bandbreite zu erhöhen und Seiten vorab zu lesen. Aber ich habe das nicht wirklich im Detail studiert.

Lassen Sie Ihr Programm zuerst korrekt arbeiten. Dann optimieren.

+0

danke für einen Kommentar. Sicherlich habe ich es schon geschafft, deshalb experimentiere ich mit Optimierungen. mmap() ist nicht tragbar. – MadH

0

Sie können

QTextStream (QIODevice * device) 

Die QTextStream-Klasse bietet eine komfortable Schnittstelle zum Lesen und Schreiben von Text .

QTextStream kann mit einem QIODevice, einem QByteArray oder einem QString arbeiten. Mit QTextStreams Streaming-Operatoren können Sie bequem lesen und schreiben Wörter, Zeilen und Zahlen.

Verwandte Themen