__autoload Benchmarks
Mittlerweile kennen die meisten
PHP-Programmierer die neue Funktionalität der autoload-Funktion. Mit
der Funktion ist es möglich, eine Callback-Funktion einzuführen, die in
der Lage ist, eine Klasse zu laden, wenn versucht wird, eine
nicht-existente Klasse aufzurufen, sei es das Erstellen einer Instanz,
der statische Aufruf oder als Parametertyp. Sie erspart einem sehr viel
Arbeit, da man die gesamten require_once's weglassen kann. Allerdings
hatte ich beschlossen, zu Beginn des Projekts darauf verzichten, damit
ich einen guten Überblick über die gegenseitigen Abhängigkeiten habe,
was sich mittlerweile als Fehler herausgestellt habe.
Um zu wissen, wie gut MVCLite läuft, habe ich ein Benchmark mittels ab
durchgeführt. Das Resultat waren 140 Requests pro Sekunde, was
eigentlich schon sehr gut ist. Gestern habe ich einige weitere Tests
durchgeführt, indem ich per Eclipse alle "require_once '*';" entfernt
und eine autoload-Methode eingeführt haben.
function __autoload ($class) {
include str_replace('_', '/', $class) . '.php';
}
Sofort danach habe ich ein Benchmark mit ab vom Apache HTTPd durchgeführt. Plötzlich konnte MVCLite 260 Requests pro Sekunde bewältigen. Ich war wirklich erstaunt. Das ist umgerechnet eine Verbesserung von 85%! Da ich die Implementation der __autoload nicht präferiere und eine möglichst nahtlose Integration in andere Bibliotheken anstrebe, habe ich stattdessen eine Implemention in meinen MVCLite_Loader vorgenommen. Ich habe einfach spl_autoload_register genutzt, um die Methode loadClass meines MVCLite_Loaders zu nutzen. Plötzlich hatte ich nurmehr 200 Requests pro Sekunde. Nach einigen Tests bin ich allerdings auf des Rätsels Lösung gekommen:
public static function loadClass ($name) {
require_once self::_format($name) . '.php';
}
Dieses require_once sorgte dafür, dass ich ca. 23% an Geschwindigkeit verloren habe. Resümierend lässt sich also sagen, dass Autoload-Funktionen mit include oder require genutzt werden sollten.
Um MVCLite mit diversen MVC-Frameworks zu vergleichen, habe ich Paul M. Jones' Neujahrs-Benchmarks genutzt und dessen Werte in Relation zu meinen gesetzt.
Als erstes habe ich berechnet, wie viele Requests eine reine PHP mit
"Hello World" schafft. Dabei bin ich auf 999 Requests pro Sekunde
gekommen. Diese habe ich dann in Relation zu seinem Wert (1434)
gesetzt. 999/1434 ergibt also den Faktor um seine Werte auf meine Skala
zu bringen. Daraus folgt dann folgende Gleichung:
rel = 260/((999/1434)*53)
Die 53 wird bei Paul M. Jones als Basiswert genutzt - ist im Übrigen
die Anzahl der Requests, die Symfony 0.6.3 schafft. Ich komme im
Übrigen auf einen rel-Wert von 7,04, was deutlich schneller ist, als
die aufgelisteten Frameworks.
Auch wenn diese Benchmarks nicht aussagefähig sind, was die
letztendliche Responsiveness betrifft, kann man jedoch behaupten, ich
befände mich auf dem richtigen Weg. Ich will eine leichtgewichtige
Implementation schaffen, wofür die Zahlen Bände sprechen. In punkto
Funktionalitäten hänge ich den anderen Frameworks natürlich nach, aber
das gehört schließlich zum Konzept von MVCLite. Abschließend noch eine Auflistung der Klassen, die bei mir geladen werden:
- MVCLite_Loader
- MVCLite_Db
- MVCLite_Db_PDO
- MVCLite_Db_Adaptable
- MVCLite
- MVCLite_Request_Dispatcher
- MVCLite_Request_Route_Standard
- MVCLite_Request_Route
- MVCLite_Request
- MVCLite_Request_Global_Synchronizable
- MVCLite_Request_Global_Cookie
- MVCLite_Request_Global
- MVCLite_Request_Global_Get
- MVCLite_Request_Global_Post
- MVCLite_Request_Global_Request
- MVCLite_Request_Global_Server
- MVCLite_Request_Global_Session
- MVCLite_Controller_Abstract
- MVCLite_Loader_Exception
- MVCLite_Exception
- MVCLite_Request_Dispatcher_Exception
- MVCLite_Request_Exception
- MVCLite_View_Layout
- MVCLite_View