Nun haben ich im ersten Teil darüber gesprochen, warum ich Kritik an der Schnittstelle zum Einbinden in das Hook-System in Drupal 7 ausübe. In diesem Beitrag gehe ich nun auf das Laufzeitverhalten bei der Ausführung der einzelnen Hooks ein.
Machen wir also ein kleines Rechenbeispiel anhand des zuvor genutzten Hooks (hook_enable()
). Aufgrund der Schnittstelle die auf einem Schema der Methodennamen in Drupal 7 basiert, muss für die Ausführung eines einzelnen Hooks die Namen aller global definierten Methoden überprüft werden. Sagen wir also mal es sind nur 1.000 Methoden (M) definiert. Also werden alle Methoden durchlaufen und überprüft, ob die Methodennamen mit _enable()
enden. Der Absolute Worstcase wäre hier, wenn unter den 1.000 Methoden keine einzige Methode dem Namensschema entspricht.
Das ganze könnten wir nun weiter spinnen, indem wir sagen bei einem Aufruf von Drupal 7 werden z. B. 100 Hooks (H) ausgeführt, wobei bei jedem Hook alle Methodennamen überpüft werden müssen. Damit ergibt sich die nachfolgende Rechnung:
o² = H * M = 100 Hooks * 1.000 Methoden = 100.000 Vergleiche
Gehen wir hier nun auch wieder von dem Worstcase aus und sagen die 1.000 Methoden sind alles nur Hilfsmethoden und entsprechen keinem dem Namensschema der 100 Hooks. Damit hätte Drupal 7 über 100.000 Vergleiche ausgeführt, welche absolut keinen Nutzen hatten. Beide einer Verdopplung der Anzahl der Hooks und Methoden vervierfacht sich nun sogar die Anzahl der Vergleiche.
o² = H * M = 200 Hooks * 2.000 Methoden = 400.000 Vergleiche
Bei weiteren Erhöhungen der Anzahl von Hooks und Methoden ist Drupal 7 sehr schnell im mehrstelligen Millionenbereich, da es sich hier um ein quadratisches Laufzeitverhalten handelt. Wobei die Trefferquote der Vergleiche nicht sehr hoch sein wird. Schauen wir uns das ganze nun mal in einem alternativen CMS wie WordPress an. Fangen wir nun wieder mit dem Beispiel eines einzelnen Hooks an. Bei WordPress erfolgt im Gegensatz zu Drupal 7 eine direkte Zuweisungen der Methoden zu einem Hook, dies bedeutet wir haben hier ein Array pro Hook mit allen zugewiesenen Methoden. Bei eine Zuweisung von 1.000 Methoden ist kein einziger Vergleich notwendig und die Methoden können ohne weiter Filterung direkt ausgeführt werden. Durch das direkte Mapping liegt die Trefferquote bei WordPress entsprechend immer bei 100%.
$enable = [ function() {...}, function() {...}, ... ];
Erweitern wir das Beispiel nun wieder auf die 100 Hooks. Dabei fällt auf wir benötigen immer noch keine Vergleiche und die 1.000 Methoden können weiterhin ohne weitere Filterung aufgerufen werden. Entsprechend wird nur ein 2-dimensionales Array intern vorgehalten:
$hooks = [ 'enable' = [ function() {...}, function() {...}, ... ], ... ];
Nun könnte der eine oder andere Entwickler sagen, hier haben wir wieder die klassische Balance zwischen den beiden Ressourcen Prozessor und Arbeitsspeicher. Aber Drupal 7 hat hier seinen Fehler eingesehen und entsprechend einen Cache eingebaut, um den erheblichen Performanceeinbußen entgegenzuwirken. Das Caching in Druapl 7 generiert dieselbe intern Datenstruktur, welche in WordPress schon indirekt durch die Schnittstelle aufgebaut wird. Nun scheinen alle Performance Probleme beim Drupal 7 Hook-System beseitigt zu sein, aber leider musste ich feststellen das Drupal 7 mit Nichten sofort neu definierte Methoden erkennt und den Cache aktualisiert. Daraus folgt für Entwickler eine regelmäßige Leerung des Cache oder den Cache bei der Entwicklung immer zu deaktivieren.
Darum nun wieder mein Aufruf das mit dem Austausch vieler Core-Komponenten mit Drupal 8 bitte nicht dieselben Fehler wie in Drupal 7 gemacht werden dürfen, damit diesem CMS in Zukunft noch irgendeine Relevanz zu gesprochen werden kann. Sonst ist der Zug irgendwann endgültig abgefahren.