München, 08.02.2012: Georg Sergl zum Thema „Optimization last: Der richtige Weg?“

In den letzten Jahren wurde viel über die Geschwindigkeit moderner Sprachen wie Java und C# philosophiert. Tatsache ist, dass es sprachimmanente Gründe gibt, warum diese Sprachen in ihrer Reinform in Echtzeitsystemen nicht zum Einsatz kommen können (die Ausnahme sind die speziellen Embedded-Versionen). Dass diese Sprachen jedoch per se moderne Applikationen langsam werden lassen, ist eher ein Trugschluss.

Uns zeigt sich immer wieder, dass die Annahme, eine saubere Architektur würde optimaler Performance im Wege stehen, irrig ist.

Bei umfangreichen Projekten hat sich der folgende Weg als sehr tragfähig erwiesen

  1. Fachliche begründeter Komponentenaufbruch
  2. Design der Komponentenschnittstellen und im zweiten Schritt der einzelnen Klassen
    Hierbei ist die Berücksichtigung der objektorientierten Prinzipien (z.B. Delegation) extrem wichtig. Auch bei der Entscheidung für Container sollte der Architekt Sorgfalt walten lassen und gleich einen fachlich wirklich passenden Typ nutzen oder den Container zusätzlich kapseln.
  3. Implementieren und Integrieren der Lösung, wobei Lesbarkeit und Wartbarkeit vorrangig im Fokus liegen sollen
    Bei der Implementierung sollte durch ordentlichen Programmierstil künstliche Verlangsamung vermieden werden. Dies kann insbesondere durch klugen Pattern-Einsatz unterstützt werden.
  4. Performance-Messungen
  5. Optimierung

Die erste wichtige Erkenntnis ist, dass die Performance-Messung typischerweise Flaschenhälse aufdeckt, mit denen niemand gerechnet hat. Häufig genug kommt es vor, dass bei der Implementierung Daten wiederholt berechnet werden, die auch zwischengespeichert werden könnten. Hier liegt in den meisten Fällen das größte Optimierungspotential, das bei guter Architektur ohne Designänderung ausgeschöpft werden kann.

Auch sub-optimale Algorithmen, die eventuell lineares oder gar schlechteres Zeitverhalten aufweisen, lassen sich so schnell entdecken und durch lokale Optimierung der Zugriffslogik oft auf O(1) optimieren.

Warum ist es von Vorteil, diese Optimierungen nachgelagert durchzuführen?

  1. Im ersten Schritt kann die Funktion des Systems qualitätsgesichert werden, ohne dass technisch bedingte Konstrukte die Applikation komplizieren
  2. Im zweiten Schritt kann das Refactoring unter beständigem Testen erfolgen, wobei klar ist, dass das System fachlich schon einmal funktioniert hat. Die Zahl der Baustellen ist somit überschaubar
  3. Schwer wartbare Konstrukte durch “vorauseilende” Optimierung werden vermieden

IMG_8959_frei
Georg Sergl
Geschäftsführer der Art of Quality GmbH