einen schnellen Parser in Python schreiben

8

Ich habe einen praktischen rekursiven reinen Python-Parser für ein bestimmtes Dateiformat ( ARFF ) geschrieben ) verwenden wir in einer Vorlesung. Jetzt läuft meine Übungseingabe furchtbar langsam. Es stellt sich heraus, dass die meiste Zeit in meinem Parser verbracht wird. Es kostet viel CPU-Zeit, die HD ist nicht der Flaschenhals.

Ich frage mich, welche performanten Möglichkeiten es gibt, einen Parser in Python zu schreiben? Ich würde es lieber nicht in C umschreiben. Ich habe versucht, jython zu benutzen, aber das hat die Performance stark reduziert! Die Dateien, die ich analysiere, sind teilweise sehr groß (& gt; 150 MB) mit sehr langen Zeilen.

Mein aktueller Parser benötigt nur ein Vorausschauzeichen für ein Zeichen. Ich würde die Quelle hier posten, aber ich weiß nicht, ob das eine so gute Idee ist. Nach all dem ist die Abgabefrist noch nicht beendet. Der Fokus in dieser Übung liegt jedoch nicht auf dem Parser. Sie können wählen, welche Sprache Sie verwenden möchten, und es gibt bereits einen Parser für Java.

Hinweis: Ich habe ein x86_64 System, also ist Psyco (und es scheint auch PyPy) keine Option.

Update: Ich habe meinen Parser / Writer nun auf bitbucket hochgeladen.

    
panzi 27.04.2010, 16:24
quelle

2 Antworten

8

Du könntest ANTLR oder pyparsing verwenden, Sie könnten Ihren Analyseprozess beschleunigen.

Und wenn Sie Ihren aktuellen Code behalten möchten, sollten Sie sich Cython / PyPy , was deine Leistung erhöht (manchmal bis zu 4x).

    
wvd 27.04.2010 16:30
quelle
7

Der allgemeinste Tipp, den ich ohne weitere Informationen geben würde, wäre, die gesamte Datei oder zumindest einen wesentlichen Teil davon sofort in den Speicher einzulesen. Du willst es nicht Charakter für Buchstabe lesen und hier und da suchen; Unabhängig von der Pufferung, die unter der Haube abläuft, ist es wahrscheinlich eine gute Idee, das Ganze im Speicher zu haben, damit man es wie gewünscht bedienen kann.

Ich habe Parser in Python geschrieben, und es gibt keine besondere Anforderung dafür, dass sie besonders langsam sind als ein Parser, der in einer anderen Sprache geschrieben ist. Wie bei solchen Dingen ist es wahrscheinlicher, dass du Arbeit machst, die du nicht tun musst. Von diesen Objektklassen ist das Erstellen und Zerstören und Wiederherstellen desselben Objekts teurer als das bloße Ablegen. Einen Wert immer und immer wieder neu zu berechnen ist teurer als nur irgendwo zu speichern. Usw., usw.

In Python führt eine Falle, in die Leute hineinfallen, eine Menge unnötiger Stringmanipulationen durch. Hängen Sie Zeichenfolgen nicht an Zeichenfolgen an. Wenn Sie Ihre Token aufbauen, arbeiten Sie an der "Master" -String und entfernen Sie den Token auf einen Schlag. (Mit anderen Worten, indexieren Sie in die "Master" -Zeichenkette, ermitteln Sie die Start- und Endpunkte, und fassen Sie sie dann mit token = master[start:end] .) Eine String-Verkettung von einem Zeichen zu einem anderen ist ein kurzer Weg zum Performance-Elend. Ich vermute, selbst wenn du aus irgendeinem Grund for c in master: newstr += c willst / brauchst, hast du vielleicht mehr Glück, die 'c's in eine Liste zu stopfen und dann newstr = ''.join(newstr_charlist) .

    
dash-tom-bang 27.04.2010 17:03
quelle

Tags und Links