Ist XML mit Perl effektiv?
Maik Görgens
- meinung
Hallo!
Ich arbeite derzeit mit XML und Perl (vor allem mit dem Perl-Modul XML::DOM).
Allerdings braucht es (logischerweise) eine gewisse Zeit, um die XML-Dateien zu parsen.
Wenn es mehrere werden kann das schon mal über die mehrere Sekunden hinaus gehen, was ja im Web schon zienlich viel ist, wenn man das Interpretieren der Perl-Scripts das Übertragen der Ausgabe zum Client etc. mitzählt.
Es ginge ja sicher auch oftmals einfacher Datenbanken oder ähnliches einfach im CSV-Format zu speichern und dann mit einem regulären Ausdruck auszulesen.
Dieses Forum ist ja auch komplett XML-basierend läuft aber trotzdem (wie es mir erscheint) sehr schnell, bei teilweise sicher sehr großen XML-Dateien.
Meine Fragen nun konkret:
Lohnt es sich im allg. XML (der Strukturierung wegen) einzusetzen, obwohl es vielleicht auch einfacher ginge?
Welche Möglichkeiten gäbe es solche Vorgänge zu beschleunigen.
Werden in diesem Forum irgendwelche Optimierungen in dem Bereich eingesetzt.
Mir ist schon klar, das es auf die erste Frage keine eindeutige Antwort geben wird, aber es würden mich mal ein paar Meinungen interessieren.
Viele Grüße
Maik Görgens
Hallo,
Lohnt es sich im allg. XML (der Strukturierung wegen) einzusetzen, obwohl es
vielleicht auch einfacher ginge?
IMHO ja, durchaus.
Welche Möglichkeiten gäbe es solche Vorgänge zu beschleunigen.
Benutze ein anderes Parser-Modul als XML::DOM. XML::DOM ist ca. 10x langsamer als
ein herkoemmlicher DOM-Parser.
Werden in diesem Forum irgendwelche Optimierungen in dem Bereich eingesetzt.
Die Index-Datei wird ueber einfache, regulaere Ausdruecke geparsed. Anfangs wurde
auch dafuer XML::DOM benutzt, aber das war einfach zu langsam.
Gruesse,
CK
Halihallo
Ich arbeite derzeit mit XML und Perl (vor allem mit dem Perl-Modul XML::DOM).
Allerdings braucht es (logischerweise) eine gewisse Zeit, um die XML-Dateien zu parsen.
das braucht es auch in anderen Ansätzen. Wenn z. B. eine CSV über RegExp eingelesen wird, muss die Datei auch eingelesen werden und dann die RegularExpressionEngine anlaufen (und die ist auch nicht grad super-schnell).
Wie Christian sagt, XML::DOM ist sehr langsam... XML::SAX und XML::Parser sind da schon viel, viel schneller.
Wenn du ein schnelles Script brauchst: Verwende XML::Parser (oder XML::SAX), der basiert auf Expat (in C programmiert => *verdammt* schnell); dort kannst du dann verschiedene Handler definieren (eg. für Tag-Start, Tag-End, Text, CDATA, ...) und so ein eigenes XML-Interface basteln...
Viele Grüsse
Philipp
use Mosche;
Wenn z. B. eine CSV über RegExp eingelesen wird, muss die Datei auch eingelesen werden und dann die RegularExpressionEngine anlaufen (und die ist auch nicht grad super-schnell).
Bitte? Bei CSV verwendet man DBD::CSV oder parst es im Notfall (=Modul nicht vorhanden) selber mit split() (obwohl ich mir da nicht sicher bin, ob es nicht auch die RegEx-Engine anwirft).
use Tschoe qw(Matti);
Halihallo Matti
Wenn z. B. eine CSV über RegExp eingelesen wird, muss die Datei auch eingelesen werden und dann die RegularExpressionEngine anlaufen (und die ist auch nicht grad super-schnell).
Bitte? Bei CSV verwendet man DBD::CSV oder parst es im Notfall (=Modul nicht vorhanden) selber mit split() (obwohl ich mir da nicht sicher bin, ob es nicht auch die RegEx-Engine anwirft).
sowohl DBD::CSV, wie auch split greifen IMHO auf Regexp zurück (obwohl wahrscheinlich einige Optimizer verwendet werden) => eigener Regexp wohl am schnellsten. Bei DBD::CSV muss der SQL-Query zudem noch über SQL::Parser geparsed werden.
$t = 'test<hello>test2<bla>test3';
print join(', ', split(/<(.*?)>/, $t));
wahrscheinlich wird dies durch RegExp gemacht, wobei
$t = 'test;test2;test3';
print join(', ', split(/;/, $t));
nicht über RegExp geschieht.
z. B. in php muss diese Unterscheidung manuell geschehen. Explode für "einfache" und split für "komplexe" splitts... Ob dies in Perl automatisch geschieht, bin ich mir nicht sicher (ich hoffe es jedoch).
Viele Grüsse
Philipp
Halihallo
Wenn z. B. eine CSV über RegExp eingelesen wird, muss die Datei auch eingelesen werden und dann die RegularExpressionEngine anlaufen (und die ist auch nicht grad super-schnell).
Bitte? Bei CSV verwendet man DBD::CSV oder parst es im Notfall (=Modul nicht vorhanden) selber mit split() (obwohl ich mir da nicht sicher bin, ob es nicht auch die RegEx-Engine anwirft).
Äm, übrigens: Natürlich würde ich das auch über split machen... Hätte ich natürlich beim Ausgangsposting einfliessen lassen sollen. Aber wenn Maik schon von RegExp spricht, habe ich das einfach, ohne zu überlegen, übernommen.
Bei einer reinen RegExp Methode, müsste man mit einer Schleife arbeiten und dazu noch einen RegExp-Replace verwenden, um gefundene Einträge zu eliminieren, bzw. über einen substr um die Daten zu löschen... Sehr ineffizient => split geht da viel, viel einfacher und schneller.
Viele Grüsse
Philipp
use Mosche;
Wenn z. B. eine CSV über RegExp eingelesen wird, muss die Datei auch eingelesen werden und dann die RegularExpressionEngine anlaufen (und die ist auch nicht grad super-schnell).
Bitte? Bei CSV verwendet man DBD::CSV oder parst es im Notfall (=Modul nicht vorhanden) selber mit split() (obwohl ich mir da nicht sicher bin, ob es nicht auch die RegEx-Engine anwirft).
Äm, übrigens: Natürlich würde ich das auch über split machen... Hätte ich natürlich beim Ausgangsposting einfliessen lassen sollen. Aber wenn Maik schon von RegExp spricht, habe ich das einfach, ohne zu überlegen, übernommen.
Tja, ich war ein bißchen schlecht gelaunt - das Posting hätte ich mir schenken können. Zumindest hätte ich die Ironie-Tags setzen können, damit jeder erkennen könnte, das ich nur mal einen kleinen Perl/Module/Selbermachen Streit auslösen wollte.
Tut mir leid, dass es dich getroffen hat - war grad keine ZweiFrames-Frage in Sicht :-)
Nichts für ungut
use Tschoe qw(Matti);
Halihallo Matti ;)
Wenn z. B. eine CSV über RegExp eingelesen wird, muss die Datei auch eingelesen werden und dann die RegularExpressionEngine anlaufen (und die ist auch nicht grad super-schnell).
Bitte? Bei CSV verwendet man DBD::CSV oder parst es im Notfall (=Modul nicht vorhanden) selber mit split() (obwohl ich mir da nicht sicher bin, ob es nicht auch die RegEx-Engine anwirft).
Äm, übrigens: Natürlich würde ich das auch über split machen... Hätte ich natürlich beim Ausgangsposting einfliessen lassen sollen. Aber wenn Maik schon von RegExp spricht, habe ich das einfach, ohne zu überlegen, übernommen.
Tja, ich war ein bißchen schlecht gelaunt - das Posting hätte ich mir schenken können. Zumindest hätte ich die Ironie-Tags setzen können, damit jeder erkennen könnte, das ich nur mal einen kleinen Perl/Module/Selbermachen Streit auslösen wollte.
Und ich bin darauf reingefallen...
Tut mir leid, dass es dich getroffen hat - war grad keine ZweiFrames-Frage in Sicht :-)
Du hast mir soeben den Tag versaut *g*...
Aber meine Postings als Äquivalent für ZweiFrames-Postings zu benutzen verzeih ich dir nie ;-)
Viele Grüsse
Philipp
PS: tausend smilies für dich, dass du wieder gute Laune hast! => :-) :-) :-) :-)
Hallo Matti,
Bitte? Bei CSV verwendet man DBD::CSV oder parst es im Notfall (=Modul nicht
vorhanden) selber mit split() (obwohl ich mir da nicht sicher bin, ob es nicht
auch die RegEx-Engine anwirft).
Der erfahrene Perl-Programmierer weiss natuerlich, dass split() langsamer ist als
ein RegEx in der Form von
@matches = $var =~ /(regex)/g;
Gruesse,
CK
Halihallo Christian
Bitte? Bei CSV verwendet man DBD::CSV oder parst es im Notfall (=Modul nicht
vorhanden) selber mit split() (obwohl ich mir da nicht sicher bin, ob es nicht
auch die RegEx-Engine anwirft).
Der erfahrene Perl-Programmierer weiss natuerlich, dass split() langsamer ist als
ein RegEx in der Form von
@matches = $var =~ /(regex)/g;
Im Ernst? - Dann ist split() ja der reinste unsinn... Wozu gibt's denn diese Funktion? - Etwa nur für die, die kein RegExp mögen und das lieber in einer funktion gepackt haben? - Und warum funktioniert das intern denn nicht gleich?
Viele Grüsse
Philipp
Hi!
Hier kann ich ja mal ansetzen, das weiß ich nämlich ;)
split ist grundlegend schonmal keine Funktion, sondern ein Operator.
Auch hier wird die Regex-Maschine angeworfen, nur das man hier nicht die Treffer, sondern das Zeug dazwischen erhält. Das heißt man kann auch Reguläre Ausdrücke als ersten paramter übergeben.
Bsp: @foo = split(/\d/,$string);
Beim CSV-Problem ist es wohl besser direkt nen Regulären Ausdruck zu verwenden, weil bei split zum Beispiel bei Werten wie "bla"bla" Fehler entstehen.
An dieser Stelle kann ich Reguläre Ausdrück vom O'Reilly-Verlag empfehlen, da steht auch für Interessierte alles zum Split-Operator drin.
An dieser Stelle auch Vielen Dank für eure Tipps und Hinweise.
Viele Grüße
Maik Görgens
Hallo Philipp,
Im Ernst?
Naja, war etwas gelogen. Kommt auf die Datenmengen an. Und auf die Komplexitaet
eines Regex. Beispielsweise eine Zeile(!) mit 10k Datensaetzen ist schneller
mit split zu parsen als mit einem RegEx. Muss man halt immer schauen, welche
Daten man erwartet.
- Dann ist split() ja der reinste unsinn... Wozu gibt's denn diese
Funktion? - Etwa nur für die, die kein RegExp mögen und das lieber in einer
funktion gepackt haben?
Nein, split() arbeitet anders. split() kann ja auch viel mehr als so ein
einfacher RegEx. Ich erinnere an 'split /ma(tch)/' oder 'split //'.
- Und warum funktioniert das intern denn nicht gleich?
Weil split() andere Funktionalitaet bietet und bei grossen Datenmengen
effizienter arbeiten kann(!), muss aber nicht.
Gruesse,
CK
Halihallo Christian
Im Ernst?
Naja, war etwas gelogen.
Böser du! *g*
Kommt auf die Datenmengen an. Und auf die Komplexitaet
eines Regex. Beispielsweise eine Zeile(!) mit 10k Datensaetzen ist schneller
mit split zu parsen als mit einem RegEx. Muss man halt immer schauen, welche
Daten man erwartet.
Ach hier liegt der Hund begraben! - Danke.
Nein, split() arbeitet anders. split() kann ja auch viel mehr als so ein
einfacher RegEx. Ich erinnere an 'split /ma(tch)/' oder 'split //'.
Yo, stimmt.
- Und warum funktioniert das intern denn nicht gleich?
Weil split() andere Funktionalitaet bietet und bei grossen Datenmengen
effizienter arbeiten kann(!), muss aber nicht.
Vielen Dank für die Informationen (werd ich bestimmt irgendwo brauchen können)
Viele Grüsse
Philipp
Halihallo nochmals
Bitte? Bei CSV verwendet man DBD::CSV oder parst es im Notfall (=Modul nicht
vorhanden) selber mit split() (obwohl ich mir da nicht sicher bin, ob es nicht
auch die RegEx-Engine anwirft).
Der erfahrene Perl-Programmierer weiss natuerlich, dass split() langsamer ist als
ein RegEx in der Form von
@matches = $var =~ /(regex)/g;
Benchmark: timing 2000000 iterations of regexp, split...
regexp: 3 wallclock secs ( 3.45 usr + 0.00 sys = 3.45 CPU) @ 579710.14/s (n=2000000)
split: 4 wallclock secs ( 3.63 usr + 0.00 sys = 3.63 CPU) @ 550964.19/s (n=2000000)
Rate split regexp
split 550964/s -- -5%
regexp 579710/s 5% --
Bei kleineren iterations wird der Unterschied grösser.
Krass, hätt ich nicht gedacht...
Viele Grüsse
Philipp
Sup!
Effektiv ist alles, was einen Effekt hat, worum es geht, ist Effizienz.
Gruesse,
Bio
Hallo Maik,
imho: ...
* Perl ist perfekt um einen Strom von "relativ ungeordneten" Daten über Reguläre Ausdrücke u.a. zu verarbeiten - dafür wurde es als Systemadmin-Tool von Larry auch ursprünglich entwickelt. Logdateien, etc. auswerten
* Perl ist nicht besonders geeignet für hochgradig strukturierte Daten, wie sie u.a. XML darstellen. Ein Indiz hierfür ist ja u.a., daß Perl (.. in seiner jetztigen Form) keine komplexen Datenstrukturen (Struct, Record, "richtige" Objekte) kennt. Das Herumgepfriemel mit Pointer-Elementen in annonymen Hashes ist da höchstens eine Notlösung.
daraus folgt für mich: Perl und XML sind kein Dream Team. Für die XML Ver-/Bearbeitung würde ich Java nehmen (insbesondere die des Apache XML Projekts).
Dies die IMHO eines eingefleischten Perl-Befürworters.
Ansonsten ist klar, daß XML::DOM eine sehr langsame Alternative ist (übrigens nicht nur mit Perl!). Einer der SAXX Parser, die das CPAN bietet, ist da - vor allem bei größeren Datenbeständen - wesentlich Effizienter.
Auf der anderen Seite, wenn Du fit in Perl bist, bieten Dir die CPAN Module einen effektiven (aber eban nicht unbedingt Laufzeit-effizienten) Weg, XML zu verarbeiten.
XML der Effizienz wegen mit RexExen zu bearbeit habe ich auch eine Zeit lang gemacht, geht aber imho am Sinn der Sache vorbei.
Herzliche Grüße
K@rl