Perl, Syntax und Performance

Ich bin ziemlich verblüfft, welche Performance-Effekte eine kompaktere Perl-Syntax erzielen kann. Doch der Reihe nach:

Ein cron-Job fragt via isql eine Sybase-Datenbank auf einer Solaris9-Maschine ab, schreibt die Ausgabe in eine Textdatei. Diese Ausgabe besteht aus jeweils zu entsorgendem Header und Trailer sowie zeilenweise Mailadressen, die wiederum ein führendes und viele nachfolgende Leerzeichen haben. Ich möchte nur die Mailadressen in einer Zeile haben, diese Datei mit etwa 5.000 Zeilen / Mailadressen wird abschließend in das Listen-Verzeichnis des Majordomo kopiert.

Nachfolgend sei die innere Verarbeitungsschleife der perligen Mailadressen-Extraktion in der jeweiligen Variante gelistet, sowie die Laufzeit (dritter Aufruf, also etwas Caching) des gesamten Shell-Skriptes (mit isql-Abfrage, Perl-Skript sowie Kopiererei) angegeben:

Variante 1:


while (<FPI>)
{
if (/^(\s)([a-zA-Z0-9][a-zA-Z_0-9-\.]*)(\@)([a-zA-Z0-9][a-zA-Z_0-9-\.]*[a-zA-Z0-9])(\.)([a-zA-Z0-9]*)/)
{
s/\s//g;                     # das leading und alle trailing Spaces entsorgen
print FPO $_ . "\n";
}
}

$ time mailadressen.sh
real    0m1.00s
user    0m0.90s
sys     0m0.05s

Variante 2:


while (<FPI>)
{
if (/^(\s)(\w[\w|\.\-]+@\w[\w\.\-]+\.[a-zA-Z]{2,4})/)
{
print FPO $2 . "\n";   # den 2. Klammerausdruck, also die Mailadresse des REGEXP ausgeben
}
}

$ time ./mailadressen.sh
real    0m0.35s
user    0m0.24s
sys     0m0.08s 

Hier beträgt der Performance-Gewinn also roundabout 60%!

2 Comments

  1. Renée Bäcker Dienstag, 29. Januar 2008

    Der Performance-Gewinn ist nicht (nur) durch kompaktere Schreibweise begründet, bzw. “kompakter” ist hier der falsche Ausdruck, da hier funktional unterschiedliche Codesnippets vorliegen und im zweiten Snippet wurde einige ungeschickte Sachen der ersten Version verbessert.

    *) Die Substitution ist nicht mehr vorhanden (s/\s//g) *) Es gelten andere Bedingungen für das Matching einer E-Mail-Adresse *) Es wird u.U. etwas ganz anderes ausgegeben ($_ vs. $2) *) In der ersten Version wird unnötig häufig Treffer des Musters gespeichert – das kostet jede Menge Zeit *) (\s) Warum wird hier gespeichert? Hier kann man die Klammern weglassen (dann muss man halt $1 statt $2 ausgeben) – auch das spart etwas Zeit

    Allerdings werden mit diesem Code nicht alle RFC822 konforme E-Mail-Adressen gefunden. Wenn Performance nicht die große Rolle spielt, würde ich zu Email::Find (http://search.cpan.org/dist/Email-Find/) raten…

    • jl Dienstag, 29. Januar 2008

      Ja, klar, hier werden fast Äpfel mit Birnen verglichen, da zwei Änderungen mit einem Mal zur Geltung kommen.

      Das sinnlose Space nicht zu speichern und dafür $1 auszugeben bringt 2ms:
      real 0m0.33s
      user 0m0.21s
      sys 0m0.13s

      Danke für den CPAN-Tipp!

Comments are Disabled

%d Bloggern gefällt das: