PHP-Leistung: Wie man Code profiliert und um das 10-fache beschleunigt

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Ihre PHP-Website ist langsam? Zeit, unter die Haube zu schauen

\n\n

Haben Sie schon einmal länger auf das Laden einer Seite gewartet, als Sie Ihren Morgenkaffee trinken? Ein bekanntes Problem. PHP ist eine mächtige Sprache, aber ohne die richtige Konfiguration kann sie sich in eine Schildkröte verwandeln. In diesem Artikel halten wir keine langweiligen Vorträge. Wir nehmen echten Code, profilieren ihn, finden Engpässe und beschleunigen ihn so, dass Ihr Server Ihnen dankt.

\n\n

Wir sprechen über PHP-Leistung – von einfachen Messungen bis zur tiefgehenden Profilierung. Sie erfahren, wie Sie mit Xdebug und Blackfire problematische Stellen finden und welche Optimierungsmethoden wirklich funktionieren. Los geht's!

\n\n

Schritt 1. Alles messen: von Mikrosekunden bis Megabyte

\n\n

Bevor Sie etwas optimieren, müssen Sie verstehen, wo es hakt. Die Intuition täuscht oft. Nutzen wir Werkzeuge.

\n\n

Der einfachste Weg: microtime(true)

\n\n

Für eine schnelle Überprüfung eines Codeabschnitts reicht das gute alte microtime(). Nicht elegant, aber es funktioniert.

\n\n
<?php\n$start = microtime(true);\n\n// Ihr langsamer Code\n$data = [];\nfor ($i = 0; $i < 100000; $i++) {\n    $data[] = md5($i . 'salt');\n}\n\n$end = microtime(true);\necho 'Ausführungszeit: ' . round(($end - $start) * 1000, 2) . ' ms';\n?>
\n\n

Diese Methode eignet sich für eine grobe Schätzung. Aber wenn das Projekt wächst, braucht es ernsthafte Werkzeuge.

\n\n

Xdebug – Ihr persönlicher Detektiv

\n\n

Xdebug ist der De-facto-Standard für die PHP-Profilierung. Es erzeugt Cachegrind-Dateien, die Sie in KCachegrind (Linux) oder QCachegrind (Mac/Windows) öffnen können.

\n\n

Installation über pecl:

\n
pecl install xdebug
\n\n

Aktivieren Sie die Profilierung in der php.ini:

\n
xdebug.mode = profile\nxdebug.output_dir = /tmp/profiling
\n\n

Nach der Ausführung des Skripts erscheint eine Datei im Ordner. Öffnen Sie sie in QCachegrind – Sie sehen, welche Funktion die meiste Zeit verbraucht hat. Oft eine Überraschung: nicht die Datenbank, sondern eine einfache String-Verarbeitung in einer Schleife.

\n\n

Blackfire – für diejenigen, die schöne Dashboards lieben

\n\n

Blackfire von SensioLabs (den Entwicklern von Symfony) ist ein Cloud-Profiler. Es zeigt nicht nur die Zeit, sondern auch die Anzahl der Aufrufe, Speicher und I/O. Es integriert sich mit PHPUnit, Symfony, Laravel.

\n\n

Beispiel für die Verwendung über die Kommandozeile:

\n
blackfire run php myscript.php
\n\n

Sie erhalten einen Link zu einem Web-Bericht mit Visualisierung. Praktisch, um PHP-Leistungsengpässe zu finden.

\n\n

Schritt 2. Typische Probleme und ihre Lösungen

\n\n

Nachdem wir nun profilieren können, schauen wir uns häufige Fallstricke an.

\n\n

Problem 1: N+1 Abfragen in einer Schleife

\n\n

Ein Klassiker. Sie erhalten eine Liste von Benutzern und führen dann in einer Schleife für jeden eine Datenbankabfrage durch.

\n\n

Langsamer Code:

\n
<?php\n$users = $db->query('SELECT id FROM users LIMIT 100');\nforeach ($users as $user) {\n    $orders = $db->query("SELECT * FROM orders WHERE user_id = {$user['id']}");\n    // ...\n}\n?>
\n\n

Optimierung:

\n
<?php\n$users = $db->query('SELECT id FROM users LIMIT 100');\n$ids = array_column($users, 'id');\n$orders = $db->query('SELECT * FROM orders WHERE user_id IN (' . implode(',', $ids) . ')');\n// Gruppieren nach user_id\n$grouped = [];\nforeach ($orders as $order) {\n    $grouped[$order['user_id']][] = $order;\n}\n?>
\n\n

Ergebnis: 100 Abfragen wurden zu 2. Die Leistung der PHP-Anwendung steigt um ein Vielfaches.

\n\n

Problem 2: Ineffiziente Schleifen und String-Operationen

\n\n

String-Konkatenation in einer Schleife ist böse. Verwenden Sie Arrays und implode().

\n\n
<?php\n// Schlecht\n$result = '';\nfor ($i = 0; $i < 10000; $i++) {\n    $result .= 'item' . $i . ',';\n}\n\n// Gut\n$parts = [];\nfor ($i =                

Blogs

Buchempfehlungen