© Michael Hirschka, Pixelio
Profiler identifizieren Flaschenhälse in
Perl-Programmen
Laufzeit-Tacho
von Michael Schilli
Erschienen im Linux-Magazin
2008/12
Statt hochgezüchteter Prozessoren helfen oft schon simple Tricks, um Programme zu beschleunigen. Profiler können Engpässe entdecken, in die es sich lohnt, Entwicklungszeit zu investieren.
Wer nicht den ganzen Tag mit Videospielen verplempert, kommt auch ohne die allerschnellste CPU klar und spart so nicht nur Hardwarekosten, sondern auch noch Strom und schont die Umwelt. Sollte ein Perl-Programm dann doch zu betulich zu Werke gehen, lässt es sich meist mit geringem Aufwand durch Optimierung des Code an entscheidenden Stellen beschleunigen. Meist reichen ein, zwei gezielte Eingriffe, um 90 Prozent der überhaupt möglichen Verbesserungen zu erzielen. Die restlichen 10 Prozent erfordern oft weitreichende architektonische Umbauarbeiten, die zehnmal so lange dauern und anschließend die Wartung erschweren, sodass erfahrene Entwickler dankend abwinken.
Flaschenhälse zuerst
Die Bottlenecks oder Hot Spots finden Profiler. Sie zeigen, wo ein Programm die meiste Zeit verbringt, und erlauben es dem Entwickler, solche Bereiche gezielt zu verbessern. Perl hat etliche Tools für diesen Zweck in seiner Werkzeugkiste. Setzt ein Modul beispielsweise das Logging-Framework Log4perl ein, ist es einfach, verstrichene Sekunden zusammen mit den Lognachrichten anzuzeigen und so einen zeitlichen Überblick zu erhalten.
Das simple Testskript »amzntest« (Listing 1) holt zum Beispiel mit Hilfe des CPAN-Moduls Net::Amazon Buchinformationen über das Web-API bei Amazon ab. (Sofern im Skript ein gültiges Token eingetragen ist, das es bei [2] gibt.) Ein Request dauert ungefähr eine Sekunde. Aber wo genau verbrät das Skript diese Zeit? Schon beim Einholen der Daten oder erst während der anschließenden XML-Analyse? Ein am Kopf des Skripts eingefügtes
use Log::Log4perl;
Log::Log4perl->init("timer.l4p");
aktiviert das in Net::Amazon eingebettete Log4perl-Framework und lädt die Konfigurationsdatei »timer.l4p«, derzufolge zu jeder geloggten Nachricht auch noch das Datum (»%d«) sowie die Zahl der verstrichenen Millisekunden seit dem Programmstart (»%r«) auszugeben ist. Da der Loglevel mit »DEBUG« relativ hoch und damit die ausgegebenen Nachrichten recht lang sein können, definiert Listing 2 auch noch einen so genannten Custom Cspec mit dem Kürzel »%S«.
Dieser erscheint dann statt des sonst üblichen »%m« (für die Lognachricht) im Layout und schickt eine auf 25 Zeichen verkürzte Nachricht an den Screen-Appender. Das Layout schließt mit einem plattformunabhängigen Newline-Zeichen ab, das als »%n« erscheint.

|
Abbildung 1: Log4perl gibt die Uhrzeit und die verstrichenen Millisekunden seit dem Programmstart an.
|

|
Abbildung 2: Bei einem eingesetzten Webcache entfällt der Webrequest für Wiederholer, das reduziert die Laufzeit um 75 Prozent.
|
Abbildung 1 zeigt, dass Net::Amazon bereits 79 Millisekunden nach dem Programmstart einen Webrequest an Amazon absetzt, der XML-Parser aber erst zum Zeitpunkt 739 Millisekunden seine Arbeit beginnt. Von den insgesamt vom Skript verbrauchten 800 Millisekunden nimmt also 75 Prozent der Webrequest in Anspruch.
01 #!/usr/bin/perl
02 use warnings;
03 use strict;
04 use Net::Amazon;
05 use Net::Amazon::Request::ASIN;
06
07 my $asin = "0132396556";
08
09 my $ua = Net::Amazon->new(
10 token => 'XXXXXXXXXXXXXXX',
11 );
12
13 my $req = Net::Amazon::Request::ASIN->new(
14 asin => $asin,
15 );
16
17 my $resp = $ua->request($req);
18
19 if($resp->is_success()) {
20 print $resp->as_string(), "n";
21 } else {
22 print "Error: ",
23 $resp->message(), "n";
24 }
|
1 log4perl.logger = DEBUG, App
2 log4perl.appender.App = Log::Log4perl::Appender::Screen
3 log4perl.appender.App.layout = PatternLayout
4 log4perl.appender.App.layout.ConversionPattern = %d %r %S%n
5 log4perl.PatternLayout.cspec.S = sub { substr($_[1], 0, 25) }
|
Schneller Fix
Folglich bietet es sich an, für häufig eingeholte ASIN-Nummern einen Cache einzusetzen, den Net::Amazon - wie Listing »amzncache« (Listing 3) zeigt - standardmäßig unterstützt. In der Tat reduziert sich die Skriptlaufzeit mit File::Cache als persistentem Zwischenspeicher bei Wiederholern auf 180 Millisekunden, wie in Abbildung 2 zu sehen.
01 use Cache::File;
02 my $cache = Cache::File->new(
03 cache_root => '/tmp/mycache',
04 default_expires => '30 min',
05 );
06
07 my $ua = Net::Amazon->new(
08 token => 'XXXXXXXXXXXXXXX',
09 cache => $cache,
10 );
|
01 #!/usr/local/bin/perl -w
02 use strict;
03
04 use Log::Log4perl qw(:easy);
05 Log::Log4perl->easy_init($INFO);
06
07 for(1..100_000) {
08 DEBUG "waah!";
09 }
|
Nun lässt sich freilich argumentieren, dass derlei Tricks nicht immer möglich sind. Aber entscheidend ist doch, dass fünf Zeilen Code und eine Minute Nachdenken eine Geschwindigkeitsverbesserung um den Faktor 4 erzielen.
| Whitepaper |
|
Open Source Datenintegration in der Praxis: Fallstudien und Anwendungsbeispiele
Über die letzten Jahre hinweg haben sich Open Source Lösungen als fester Bestandteil des gesamten Datenintegrationsmarktes etabliert. Viele Unternehmen haben bereits das Open Source Modell für Ihre Datenintegrationsprojekte aufgegriffen. Das vorliegende White Paper illustriert anhand ausgewählter Fallstudien und Anwendungsbeispiele die Implementierung von Open Source Datenintegration in der Praxis und benennt die daraus resultierenden Vorteile.
Download PDF (Registrierung erforderlich)
|
|
The Role of Open Source in Data Integration
Obwohl in den letzten Jahren viele technische Fortschritte erzielt werden konnten, verfügen die meisten Datenintegrationsprozesse nach wie vor nur über eine sehr begrenzte Automatisierung. Das vorliegende White Paper von dem Industry Analyst Mark Madson wird zunächst ein grundlegendes Verständnis von Daten Integration vermitteln, die Vorzüge von Open Source Lösungen für Daten Integration erläutern und Ihnen professionelle Empfehlungen geben, damit Sie Ihre Integrationsjobs noch einfacher und produktiver gestalten können.
Download PDF (Registrierung erforderlich)
|
Dieser Online-Artikel kann Links enthalten, die auf nicht mehr vorhandene Seiten verweisen. Wir ändern solche "broken links"
nur in wenigen Ausnahmefällen. Der Online-Artikel soll möglichst unverändert der gedrucken Fassung entsprechen.
|