Langsamere als erwartete Java Regex-Leistung

8

Ich wurde beauftragt, große CSV-Dateien (300k + Datensätze) zu lesen und Regexp-Muster auf jeden Datensatz anzuwenden. Ich war schon immer ein PHP-Entwickler und habe nie wirklich andere Sprachen ausprobiert, entschied aber, dass ich den Tauchgang machen und versuchen sollte, dies mit Java zu tun, von dem ich annahm, dass es viel schneller wäre.

Tatsächlich war das Lesen der CSV-Datei Zeile für Zeile in Java dreimal schneller. Als ich jedoch die Regexp-Anforderungen anwendete, erwies sich die Java-Implementierung als 10-20% länger als das PHP-Skript.

Es ist sehr gut möglich, dass ich in Java etwas falsch gemacht habe, weil ich das gerade so gelernt habe, als ich heute ging. Unten sind die zwei Skripte, jeder Rat würde sehr geschätzt werden. Ich möchte wirklich Java für dieses spezielle Projekt nicht aufgeben.

PHP CODE

%Vor%

JAVA CODE

%Vor%     
IOInterrupt 11.07.2011, 20:55
quelle

5 Antworten

4

Die Verwendung eines gepufferten Lesegeräts könnte der Performance dabei helfen, etwas besser zu werden:

%Vor%     
rsp 11.07.2011 21:15
quelle
3

Ich sehe nichts, was mit Ihrem Code grell falsch ist. Versuchen Sie, den Performance-Flaschenhals mit einem Profiler zu isolieren. Ich finde den Netbeans Profiler sehr benutzerfreundlich.

EDIT: Warum spekulieren? Profiliere die App und erhalte einen detaillierten Bericht darüber, wo die Zeit verbracht wurde. Dann arbeiten, um die ineffizienten Bereiche zu lösen. Weitere Informationen finden Sie unter Ссылка .

EDIT2: OK, mir ist langweilig geworden und habe das profiliert. Mein Code ist identisch mit Ihrem und hat eine CSV-Datei mit 1.000 identischen Zeilen wie folgt analysiert:

%Vor%

Hier sind die Ergebnisse (Ihre Ergebnisse werden sich natürlich unterscheiden, da meine regulären Ausdrücke trivial sind). Es ist jedoch klar, dass die Regex-Verarbeitung nicht Ihr Hauptanliegen ist.

Interessanterweise wird die Leistung, wenn ich einen BufferedReader anwende, um satte 18% erhöht (siehe unten).

    
hoipolloi 11.07.2011 21:06
quelle
0

Einige Punkte, die hier zu beachten sind.

  1. Sie beginnen damit, die Zeit zu messen, noch bevor die Muster kompiliert werden. Pattern.compile ist eine relativ teure Operation und benötigt möglicherweise mehr Zeit, wenn das Muster komplex ist. Warum nicht nach dem Kompilierungsschritt mit der Messung beginnen?

  2. Ich bin mir nicht sicher, wie effizient CSVReader class ist.

  3. Anstatt die übereinstimmenden Ergebnisse direkt im Hauptthread selbst auszudrucken (da System.out.println blockiert und teuer ist), könnten Sie vielleicht das Drucken an einen anderen Thread delegieren.

adarshr 11.07.2011 21:08
quelle
0

Mehrere Dinge:

  1. Die Regex muss nur einmal kompiliert werden und das sollte beim Start des Servers sein, also spielt es für die Leistung während der Ausführung keine Rolle.

  2. Und am wichtigsten ist, dass Sie einen völlig ungültigen Benchmark für ein lang laufendes Java-Programm schreiben. Sie laden sicherlich mehrere Klassen beim Benchmarking und testen nur die Leistung des Interpreters und NICHT das JIT, was offensichtlich zu einer viel schlechteren Performance führt. Siehe ausgezeichnete Post für das Schreiben ein gültiger Benchmark in Java. Dies wird sicherlich alle angeblichen Leistungsprobleme in diesem Fall beheben.

Voo 11.07.2011 21:14
quelle
0

Ich würde empfehlen:

  • wie jemand anderes vorgeschlagen hat, Profil, um zu sehen, wo der eigentliche Engpass ist;
  • sagen Sie uns, was die tatsächlichen Regexes sind: Es kann sein, dass Sie ein bestimmtes Subpattern verwenden, das in der Implementierung von Java nicht sehr effizient ist.

Es ist durchaus möglich, dass Teile der PHP-Regex-Engine für bestimmte Ausdruckstypen mehr optimiert sind als Java, und / oder es gibt eine Möglichkeit, den von Ihnen verwendeten Ausdruck zu optimieren.

    
Neil Coffey 11.07.2011 22:12
quelle

Tags und Links