Web Performance Optimization – Teil 3

25.02.2013 11:14

Algorithmen optimieren

Die Beschleunigungsmöglichkeiten der Ausführungszeiten von Algorithmen sind ein sehr breites Feld. Im Grunde müsste man sich Fachbücher über Algorithmentheorie und effiziente Programmierung zu Gemüte führen, um das komplette Potential dieser Methoden überblicken zu können. Deshalb sollen an dieser Stelle nur einige einfache Möglichkeiten angerissen werden, mit denen sich JavaScript und PHP-Skripte beschleunigen lassen.

 

Falls Sie die Übeltäter in Ihren JavaScripts nicht so recht ausmachen können, die für lange Ausführungszeiten verantwortlich sind, gibt es ein nettes Firefox-AddOn namens „Firebug“. Dieses misst die Zeit von JavaScript-Funktionen und erlaubt Ihnen somit, ein detailliertes Profiling durchzuführen. Eine grundsätzliche Regel, die man von vorn herein immer beachten

sollte, lautet: Aufwendige Rechenoperationen vermeiden, wann immer es geht. Beispielsweise sollte auf Logarithmieren oder Wurzelziehen verzichtet werden, wenn dies nicht absolut unumgänglich ist. Diese Operationen sind verhältnismäßig sehr langsam und können gerade, wenn sie in längeren Schleifen verwendet werden, zu einem regelrechten Flaschenhals der Laufzeit führen. Außerdem sollte man immer auf die von der Programmiersprache vorgegebenen Algorithmen zurückgreifen, anstatt sie mal eben selbst zu implementieren (Sortieren, Mischen, usw.). Denn es ist davon auszugehen, dass die Entwickler der Sprache eine größere Programmiererfahrung haben als man selbst. Man sollte also etwas Zeit in der Funktionsreferenz von PHP verbringen und wirklich sicherstellen, dass es einen entsprechenden Algorithmus nicht schon gibt. Nicht nur für JavaScript und PHP, sondern auch für alle weiteren Programmiersprachen gilt: Sofern es angebracht ist, sollte man Code-Inlining anwenden. Was ist damit gemeint? Inlining bedeutet, dass Codeteile nicht in einer Funktion ausgelagert, sondern direkt dort implementiert sind, wo sie gebraucht werden. Betrachten Sie dazu das Beispiel in Listing 1:

 

Listing 1

<?php
############# Ohne Code-Inlining ##############
function rechne($a, $b) {
return ($a*$a + $b*$b*$b + $a*$b/2);
}
// Hier befinden sich noch viele weitere Funktionen.
$start = microtime(true);
for ($a = 0; $a < 1000; $a++) {
for ($b = 0; $b < 1000; $b++) {
$c = rechne($a, $b);
}
}
$ende = microtime(true);
print "Zeit: ".($ende - $start)."<br />";
###############################################
############## Mit Code-Inlining ##############
$start = microtime(true);
for ($a = 0; $a < 1000; $a++) {
for ($b = 0; $b < 1000; $b++) {
$c = ($a*$a + $b*$b*$b + $a*$b/2);
}
}
$ende = microtime(true);
print "Zeit: ".($ende - $start);
###############################################
?>

 

Im ersten Teil ist der Term $a*$a + $b*$b*$b + $a*$b/2 in eine Funktion ausgelagert, im zweiten steht er direkt in der inneren for-Schleife. Warum macht das einen Unterschied? Im ersten Teil muss der PHP-Interpreter insgesamt 1 Mio. Mal die Funktion rechne() im Namensraum nachschlagen. Zudem müssen bei jedem Aufruf zunächst die Werte $a und $b kopiert werden, bevor es ans eigentliche Rechnen geht. Dieser Aufwand entfällt bei der zweiten Variante komplett, was zu einem merklichen Geschwindigkeitsvorteil führt. So wird für Variante 1 Zeit: 1.72823405266 ausgegeben und für Variante 2 Zeit: 0.629841804504. Die Laufzeit hat sich also um über 60% reduziert.

 

Einige Zeit beim Seitenaufbau kann der Browser auch dafür benötigen, JavaScript-Code auszuführen, der das DOM der Seite intensiv modifiziert. Werden Elemente ins DOM eingehängt, ist oft ein Rebuild des Seitengerüsts notwendig. Dies ist beispielsweise der Fall, wenn in einer Schleife viele <li>-Elemente in eine <ul> eingefügt werden. Hier ist es empfehlenswert, zuerst die komplette <ul> im JavaScript zu erzeugen, zu vergrößern und erst am Ende ins DOM einzuhängen. Dies hat zudem den Vorteil, dass dieser Codeabschnitt eventuell vom JIT-Compiler des Browsers (JIT = Just-In-Time) in effizienteren Bytecode umgewandelt und dadurch schneller ausgeführt werden kann. Ein Repaint fällt dagegen nicht besonders ins Gewicht. Dieser wird z. B. nötig, wenn lediglich Style-Eigenschaften von Elementen geändert werden.

 

Last but not least sei zu erwähnen, dass neue Variablen in JavaScript immer mit dem Schlüsselwort var eingeführt werden sollten. Dem Interpreter teilen Sie dadurch unmissverständlich mit, dass es diese Variable bisher noch nicht gab. Tun Sie dies nicht, wird der Interpreter zunächst den kompletten Namensraum durchsuchen, bis er feststellt, dass eine Variable mit entsprechendem Namen noch nicht existiert. So etwas wirkt sich gerade bei JavaScript stark auf die Laufzeit aus, da es in dieser Sprache eigentlich nur zwei Namensräume gibt: den globalen und den von Funktionen. Führen Sie eine neue globale Variable ein, ist diese automatisch auch in allen folgenden Funktionen verfügbar. Daher gibt das folgende kleine Skript ohne Beanstandungen den Wert 3 aus.

 

<script type="text/javascript">
var foo = 3;
function bar() {
document.write(foo);
}
bar();
</script>

 

Wenn also irgendwo in einer Funktion eine neue Variable ohne var angelegt wird, wird der Interpreter nicht nur den Namensraum der Funktion, sondern auch den kompletten globalen Namensraum durchsuchen, was gerade bei umfangreichen Codes einige Zeit dauern kann.

Im nächsten Teil der Serie "Web Performance Optimization" lesen Sie mehr zu SQL Optimierung.

 

Haben Sie den Anfang der sechsteiligen Reihe verpasst? Hier „Web Performance Optimization“ komplett lesen >>


Autor Timo Krotzky

Timo Krotzky ist freier Entwickler, Berater und Autor mit den Schwerpunkten PHP, MySQL und Java. Seine Erfahrung im Bereich Web Technologies erstreckt sich mittlerweile über mehr als 10 Jahre. Vor seinem Studienabschluss absolvierte der Diplom-Bioinformatiker eine Ausbildung zum staatl. gepr. Assistent für Wirtschaftsinformatik und war 9 Jahre lang für die AFS-Software GmbH & Co. KG tätig, wo er zuletzt für die Entwicklung von E-Commerce Lösungen sowohl im Front-End- als auch im Back-End-Bereich verantwortlich war. Seit einigen Jahren schreibt er regelmäßig für Fachzeitschriften wie Web & mobile Developer zu den Themengebieten Datenbank, Web Development und SEO.

Timo Krotzky

Developer Week in Social Media

Folgen Sie uns auf:

Aussteller & Sponsoren

Infos anfordern

Infos anfordern
  • Florian Bender
  • Projektleitung
  • Tel.: +49 (89) 74117-206
  • Fax: +49 (89) 74117-448
  • E-Mail: florian.bender@nmg.de

Medienpartner