Performance und die Ausrede der verfrühten Optimierung

Ein bekannter Spruch der Software-Entwicklung ist die Aussage "Premature optimization is the root of all evil." Dieses Zitat von Donald Knuth wird dabei meist in dieser Form aus dem Kontext gerissen benutzt und als Ausrede verwendet, um Performance-Gesichtspunkte bei der Entwicklung (erstmal) nicht beachten zu müssen. Womöglich wird gar gehofft, am Ende eines Projektes etwaige Performance-Schwachstellen mittels eines Profilers oder sonstiger magischer Tools herausfinden zu können und durch die daran anschließende Behebung der Engpässe, die Anwendung auf Trab zu bringen.

Dies ist eine irrige Hoffnung, die nur selten gelingen wird. Der Punkt an dem Zitat von Knuth ist zum einen zu entscheiden, was denn eine "premature optimization" ist und wann eine Optimization notwendig und im Zeitablauf eines Projekts angemessen ist. Zum zweiten lohnt es sich gerade bei diesem Zitat, den Kontext zu beachten, in dem es steht:

"There is no doubt that the grail of efficiency leads to abuse. Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97 % of the time: premature optimization is the root of all evil.

Yet we should not pass up our opportunities in that critical 3 %. A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code, but only after that code has been identified."

Donald E. Knuth in: Computing Surveys, Vol. 6, No. 4, 1974; Hervorhebungen im Original

Auch Brian Goetz Aussage, dass man am besten dummen Code schreibe, wird diesbezüglich gerne falsch verstanden:

"Often, the way to write fast code in Java applications is to write dumb code -- code that is straightforward, clean, and follows the most obvious object-oriented principles."

Interview mit Brian Goetz, März 2007

Goetz und Knuth haben natürlich recht. Das blöde ist nur, dass man wissen muss, wann man am besten dummen Code schreibt, wann es richtig ist, nicht zu optimieren. Randall Hyde weist in einem lesenswerten Essay darauf hin, dass die 97 Prozent von Knuth bedeuten, dass im Schnitt bei jeder 33. Codezeile Optimierung angebracht ist. Die konkreten Zahlen sind sicher eher willkürlich gewählt, sie dienen mehr dazu, das Problem deutlich zu machen.

Zunächst einmal sind zwei Dinge zu unterscheiden:

  1. Beim Design der Anwendung wird Performance berücksichtigt
  2. Beim Codieren wird auf performanten Code geachtet

Das Erstere ist immer ein Muß. Ein fehlerhaftes Design lässt sich im schlimmsten Fall nur durch ein Redesign mit entsprechendem Umschreiben des Codes korrigieren. So auch Goetz:

"Most performance problems these days are consequences of architecture, not coding -- making too many database calls or serializing everything to XML back and forth a million times."

Interview mit Brian Goetz, März 2007

De facto werden ganz wesentliche Entscheidungen, die die Performance einer Anwendung betreffen, zu einem frühen Zeitpunkt eines Projekts getroffen. Nehmen wir als Beispiel die Verteilung der Anwendung auf mehrere Knoten.

Ganz entscheidend in Knuths Zitat ist der Hinweis auf "noncritical parts". Diese zu optimieren ist, so Knuth, des Entwicklers liebstes Ding. Allerdings impliziert der Ausdruck gerade, dass es auch "critical parts" eines Programms geben müsste. Und diese zu optimieren ist sehr wohl wichtig.

Abschließend möchte ich allerdings betonen, dass das wichtigste an einem Programm ist, dass es das tut, was es tun soll - und zwar mit möglichst wenigen Fehlern und auf eine vorhersehbare Art und Weise. Ein Programm mag rennen wie Schmidts Katze und dazu die wunderbarste Benutzerführung aller Zeiten haben. Wenn es nicht das macht, was der Anwender braucht, wird der Anwender es dennoch nicht nutzen (umgekehrt wird der Anwender freilich auch nicht gerade mit Freuden altbackene und träge Anwendungen aufrufen). Gerade bei nebenläufigen Programmen kann man ein Programm wunderbar kaputt optimieren und kaum nachvollziehbare Fehlersituationen erzeugen. Dies ist für Anwender wie Entwickler in der Wartung gleichermaßen ein Albtraum! Insofern im Zweifel dann doch lieber dummen Code schreiben, bevor man sich selber austrickst!

In dem Sinne: Know when to play dumb!

RoR-Marketing-Videos

Per Zufall bin ich heute auf ein Youtube-Video gestoßen, in dem eine Ruby on Rails-Firma die Mac-Werbevideos als Vorlage genommen hat und RoR u.a. auch mit Java vergleicht. Logischerweise ist der RoR-Guy natürlich der coole Typ und der Java-Guy entspricht dem PC-Langweiler der Apple-Videos.

Das Video spricht natürlich in erster Linie Ruby-Leute an, aber auch als Java-Entwickler fand ich das Video recht amüsant. Ein wenig Selbstironie schadet nie. Und es spricht - wenn auch sehr plakativ - das allen Java-Entwicklern wohlbekannte Problem des Deployments an.

In einer ganze Folge von Videos bekommt natürlich nicht nur Java sein Fett ab, sondern auch ColdFusion, PHP oder .NET. Auf der Commercials-Seite sind alle Videos aufgelistet. Zumeist ist der Apple-Stil recht gut kopiert, allerdings kommt bspw. das PHP-Video doch ein wenig belehrend und zu konkret daher und dem RoR-Guy fehlt dann doch das Charisma des Apple-Guys. Vergleichbar ist sicherlich der Gehalt zwischen den RoR-Videos und den Apple-Videos. Aber was erwartet man schon von Marketing-Videos ;-)

Das Thema dynamische Sprachen werde ich hier im Blog sicher noch ab und an mit ernsthaften Beiträgen aufgreifen, aber für heute muss der Hinweis auf die Videos genügen.