2009-01-05 1 views
6

Ich versuche zu bestimmen, was der schnellste Weg ist, große Textdateien mit vielen Zeilen zu lesen, einige Bearbeitungen vorzunehmen und sie in eine neue Datei zu schreiben. In C#/.net scheint StreamReader eine scheinbar schnelle Methode zu sein, aber wenn ich versuche, für diese Datei zu verwenden (Zeile für Zeile), geht es etwa 1/3 der Geschwindigkeit von Pythons I/O (was mich beunruhigt) weil ich immer wieder höre, dass IO von Python 2.6 relativ langsam ist.Was ist die optimale (Geschwindigkeits-) Methode zum Parsen einer großen Textdatei (> 4 GB) mit vielen (Millionen) Zeilen?

Wenn es nicht schneller .Net Lösung hierfür ist, wäre es möglich, eine Lösung zu schreiben schneller als Stream oder ist es schon komplizierte Puffer/Algorithmus/Optimierungen verwenden, die ich würde nie zu schlagen hoffen?

+0

Eine Frage, wo ist Ihr Engpass im C# -Code? Haben Sie den Code profiliert oder gemessen? 1/3 der Geschwindigkeit von Python scheint für Operationen mit schwerem Festplattenzugriff nicht richtig zu sein. –

+0

bekommt jeder eine gültige Antwort auf diesen? Warst du gerade beim EOF oder was war deine Strategie beim Stream-Reader? –

Antwort

2

StreamReader ist ziemlich gut - wie hast du es in Python gelesen? Es ist möglich, dass, wenn Sie eine einfachere Codierung (z. B. ASCII) angeben, dies die Dinge beschleunigen kann. Wie viel CPU wird benötigt?

Sie können die Puffergröße erhöhen, indem Sie den entsprechenden StreamReader-Konstruktor verwenden, aber ich habe keine Ahnung, wie viel Unterschied das wahrscheinlich macht.

+0

Ich würde erwarten, dass die Erhöhung der Puffergröße seines StreamWriter (vermutlich verwendet er einen) einen ziemlich guten Unterschied machen würde. –

3

Haben Sie ein Codebeispiel von dem, was Sie tun, oder dem Format der Datei, die Sie gerade lesen?

Eine andere gute Frage wäre, wie viel von dem Strom Sie im Speicher zu einer Zeit halten?

0

Eine allgemeine Anmerkung:

  1. Hochleistungs-Streaming ist nicht kompliziert. In der Regel müssen Sie die Logik ändern, die die gestreamten Daten verwendet. das ist kompliziert.

Eigentlich ist es das.

0

Sorry, wenn ich kein .NET-Guru bin, aber in C/C++, wenn Sie schöne große Puffer haben, sollten Sie in der Lage sein, es mit einem LL1-Parser nicht viel langsamer zu analysieren, als Sie die Bytes scannen können. Ich kann mehr Details geben, wenn Sie wollen.

0

Probieren Sie BufferedReader und BufferedWriter aus, um die Verarbeitung zu beschleunigen.

+0

Ich denke, dass sie Java-Klassen sind. StreamReader für .Net ist bereits gepuffert. – GvS

+0

Ja, das sind tatsächlich Java-Klassen, er sucht nach einer Korrektur in C#. Wenn es Java wäre, würde ich das Gleiche empfehlen. –

0

Die von StreamReader/FileStream verwendeten Standardpuffergrößen sind möglicherweise nicht optimal für die Datensatzlängen in Ihren Daten. Sie können also versuchen, sie zu optimieren. Sie können die Standardpufferlängen in den Konstruktoren sowohl für FileStream als auch für den StreamReader überschreiben, der sie umschließt. Sie sollten sie wahrscheinlich gleich groß machen.

2

Wenn Sie Ihren eigenen Code ist ein Zeichen in einer Zeit der Prüfung, möchten Sie einen Sentinel verwenden, um das Ende eines Puffers oder das Ende der Datei zu markieren, so dass Sie nur einen Test in Ihrem inneren Schleife haben . In Ihrem Fall wird ein Test für das Ende der Zeile gelten. Sie sollten also beispielsweise am Ende jedes Puffers vorübergehend einen Zeilenumbruch anbringen.

Der Wikipedia-Artikel über Sentinels ist überhaupt nicht hilfreich; Es beschreibt diesen Fall nicht. Sie können eine Beschreibung in irgendeinem der Lehrbücher von Robert Sedgewick finden.

Sie können auch sehen, re2c, die generieren sehr schnellen Code zum Scannen von Textdaten. Es erzeugt C-Code, aber Sie können es möglicherweise anpassen, und Sie können sicherlich die Techniken durch Lesen ihrer Arbeit über re2c lernen.

Verwandte Themen