36 Punkte von GN⁺ 2026-03-19 | 1 Kommentare | Auf WhatsApp teilen
  • Regel 1: Es ist nicht vorhersehbar, wo ein Programm Zeit verbrauchen wird. Engpässe entstehen an unerwarteten Stellen, daher nicht versuchen, die Geschwindigkeit zu verbessern, bevor tatsächlich bewiesen ist, dass dort ein Flaschenhals liegt
  • Regel 2: Messen hat Vorrang. Performance-Tuning nur nach dem Messen durchführen und Optimierung nur dann in Betracht ziehen, wenn ein Teil des Codes das Ganze dominiert
  • Regel 3: Komplexe Algorithmen sind bei kleinem n langsam. Komplexe Algorithmen haben große konstante Faktoren; solange n nicht häufig groß wird, sollte man einfache Methoden verwenden. Selbst wenn n groß wird, muss zuerst Regel 2 angewendet werden
  • Regel 4: Komplexe Algorithmen sind fehleranfälliger und schwerer zu implementieren. Es ist wünschenswert, einfache Algorithmen und einfache Datenstrukturen zu verwenden
  • Regel 5: Daten sind der Kern. Wenn man die richtige Datenstruktur wählt und gut organisiert, ergibt sich der Algorithmus fast von selbst. Im Zentrum der Programmierung stehen nicht Algorithmen, sondern Datenstrukturen

Verwandte Philosophie und Zitate

  • Regel 1 und 2 haben dieselbe Bedeutung wie Tony Hoares Ausspruch „Vorzeitige Optimierung ist die Wurzel allen Übels“
  • Ken Thompson interpretierte Regel 3 und 4 als „Wenn du unsicher bist, nimm die einfache Methode (Brute Force)“ neu
  • Regel 3 und 4 sind ein Beispiel für die Designphilosophie KISS (Keep It Simple, Stupid)
  • Regel 5 wurde bereits von Fred Brooks in The Mythical Man-Month erwähnt und wird
    oft als „einfachen Code mit intelligenten Objekten schreiben“ zusammengefasst

1 Kommentare

 
GN⁺ 2026-03-19
Hacker-News-Kommentare
  • Erinnert an den Vortrag von Jonathan Blow
    Er ging das aus der Perspektive der Produktivität an. In der frühen Entwicklung von Braid hat er fast alles mit einfachen Arrays umgesetzt und nur dann etwas geändert, wenn ein Bottleneck auftrat
    Eindrucksvoll war die Aussage: „Wichtiger als Geschwindigkeit oder Speicher ist die Lebenszeit, die man braucht, um ein einzelnes Programm umzusetzen“

    • Spiele verarbeiten viele ähnliche Objekte mit mehr als 60 Frames pro Sekunde wiederholt, daher ist eine einfache arraybasierte Struktur ein vernünftiger Standard
    • In der Spieleentwicklung muss ein Frame innerhalb von 16 ms gerendert werden, daher sind Tabellen fester Größe und lineare Suche ein häufiges Muster. Das ist eine strukturelle Entscheidung, um die Unvorhersehbarkeit von dynamischer Allokation zu vermeiden
    • Diese Sichtweise gilt auch für allgemeine Entwicklung außerhalb von Spielen. Wir alle arbeiten unter Termin- und Kostendruck, also ist Engineering-Zeit selbst ein Kostenfaktor
    • Man sollte die Lehren aus der Spieleentwicklung aber nicht unbesehen auf allgemeine Programmierung übertragen. Spiele basieren eher auf zweckgebundenem Code als auf Wiederverwendung, allgemeine Software ist dagegen datenorientiert
    • Ich selbst bin eher der Typ, der statt mit Arrays mit einer Hash-Map anfängt
  • Wenn man Rule 1 wirklich ernst nimmt, folgen Rule 3 bis 5 fast von selbst
    Wenn man akzeptiert, dass sich Bottlenecks nicht vorhersagen lassen, sind einfachen Code schreiben und messen die einzig vernünftige Strategie
    In der Praxis scheitert man viel öfter nicht an verfrühter Optimierung, sondern an verfrühter Abstraktion. Man baut komplexe Schichten für Flexibilität, die man gar nicht braucht, und erhöht damit eher die Wartungskosten

    • Den Satz „Abstraktion sollte natürlich entstehen, nicht im Voraus entworfen werden“ zitieren wir im Team oft
    • Verfrühte Abstraktion verschwendet Entwicklerzeit, erhöht die technischen Schulden und steigert die Fehleranfälligkeit. Oft geschieht das unter dem Vorwand, auf „zukünftige Probleme“ vorbereitet zu sein
    • Als passender Text dazu lohnt sich Philip Wadlers Artikel
    • Mir sind Lesbarkeit und Wartbarkeit wichtiger als Performance. Deshalb ist für mich Rule 4 grundlegend, und Rule 1 ist nur die Folge davon
    • Ich habe Fälle erlebt, in denen komplexe Konfigurationsdateien übermäßig aufgespalten wurden. Am Ende reichten acht einfache YAML-Dateien völlig aus
  • Ich hatte in den 90ern einmal die Aufgabe, nachts um 2 Uhr eine Suchfunktion für Datensätze zu implementieren
    Weil ich müde war, habe ich erst einmal lineare Suche eingebaut und mir vorgenommen, das später zu korrigieren, aber in Wirklichkeit machte das in einem vierstündigen Test nur 6 Sekunden Unterschied
    Am Ende habe ich es zwar geändert, aber einen nennenswerten Unterschied gab es nicht

    • Bei kleinem n kann lineare Suche sogar schneller sein
    • O(n²)-Algorithmen bergen aber das Risiko, „zwar ausgerollt zu werden, aber am Ende im Betrieb zu explodieren
  • Rule 5 kann ich voll und ganz unterschreiben
    Je schwieriger das Problem ist, desto eher wird es durch iterative Verbesserungen an Datenstrukturen und APIs gelöst. Wenn die Struktur stimmt, ergibt sich der Kontrollfluss fast von selbst
    LLMs sind in dieser Art von strukturellem Denken schwach. Komplexe Kontrollflüsse schlagen sie gut vor, aber beim Entwurf kombinierbarer Datenstrukturen sind sie schlecht

    • Meiner Erfahrung nach ist Rule 5 praktisch Rule 1. Es gibt den Spruch: „Wenn du mir den Code zeigst, bin ich verwirrt, aber wenn du mir das Datenbankschema zeigst, wird alles klar“
    • In verteilten Services wird Rule 5 oft ignoriert. Statt mehrere HTTP- und DB-Aufrufe aufzuteilen, ist eine Struktur, die alles mit einem einzigen Aufruf erledigt, oft effizienter
  • Ich komme aus der Elektrotechnik (E.E.), und dank Rule 3 hatte ich am Anfang meiner Karriere keine großen Probleme
    Später bin ich aber zu großen Systemen gewechselt, n wurde größer, und Komplexität wurde tatsächlich wichtig
    Das „Big Iron“ aus der Zeit, von der Rob Pike sprach, ähnelte heutigen Embedded-Umgebungen

    • Ich widerspreche Rule 3 teilweise. Bei kleinen Eingaben spielt es keine Rolle, aber bei großen Eingaben ist Big-O-Performance wichtig.
      Wenn zwei Algorithmen ähnlich schwer zu implementieren sind, nehme ich bei großen Eingaben den schnelleren
      Passender Artikel: Less Than Quadratic
    • Man muss „fancy“ im jeweiligen Problembereich interpretieren. Wenn n klein ist, ist ein einfacher Ansatz besser, aber wenn n groß ist, sind ausgefeilte Algorithmen unverzichtbar
      Oft wählen Leute einen zu simplen O(n²)-Ansatz und erleben dann eine Explosion im Betrieb
    • Mein Vater hat schon seit der Fortran-Zeit gerne Lookup-Tabellen verwendet. Das ist eine klassische Optimierungsmethode, um wiederholte Berechnungen zu verringern
  • Ich finde, Pikes Regeln sind besser als die üblichen Sprichwörter
    Sätze wie „vorzeitige Optimierung ist die Wurzel allen Übels“ verlieren leicht ihren Kontext und werden missverstanden
    Pikes Version ist klarer und schwerer falsch anzuwenden
    Es gab einmal die alte Formulierung, Rule 5 lasse sich so zusammenfassen: „Lass dummen Code kluge Objekte verwenden“,
    aber im Zeitalter der Objektorientierung wurde das eher zu einem falschen Glauben, Komplexität verstecken zu können

    • Es ist wichtig, die Verbindungslinien im historischen Denken zu erhalten
    • Die Formulierung „geistiges Clickbait klassischer Sprichwörter“ wirkt auf mich wie eine witzige Metapher
  • Nachdem ich über zehn Jahre dieselbe Codebasis betreut habe, habe ich Pikes Regeln vollständig verinnerlicht
    Sich an die KISS/DRY-Prinzipien zu halten und lieber bewährte Technik als Trendtechnologien zu behalten, war langfristig stabiler
    Tatsächlich enthält das Prinzipiendokument unseres Teams fast genau dasselbe wie Pikes Regeln

  • Anfang der 1990er, in der C++-Zeit, habe ich einmal eine doppelt verkettete Liste durch einfaches Reallokieren eines Arrays ersetzt,
    und nicht nur verschwanden die Bugs, es wurde sogar schneller.
    Dabei habe ich gelernt, dass es eine gute Strategie ist, teure Operationen seltener auszuführen

  • Spannend ist der Vergleich zwischen der Regel „nicht ohne Messung optimieren“ und Jeff Deans Latency Numbers Every Programmer Should Know
    Dean sagt, man könne mit Vorwissen Performance vorhersagen
    Letztlich lassen sich beide Positionen vereinen — beim Entwurf wählt man intuitiv eine schnelle Struktur, und nach der Implementierung feinjustiert man auf Basis von Messungen

    • Wirklich schneller Code nutzt beides. In der Entwurfsphase wird Cache-Effizienz berücksichtigt, danach werden per Profiling die Bottlenecks entfernt
    • Latenzwerte zeigen nur die theoretische Untergrenze eines Algorithmus, die tatsächliche Performance hängt aber von Implementierung und Laufzeitumgebung ab
    • Was „vorzeitige Optimierung“ verbietet, ist lokales Tuning auf Hack-Niveau. Im Gesamtdesign Geschwindigkeit zu berücksichtigen, ist selbstverständlich
  • Rule 1 und 2 sind nur dann absolut, wenn man ein neues Problem angeht
    Wenn man in derselben Domäne wiederholt Systeme baut, kann man Bottlenecks im Voraus vorhersagen
    Erfahrene Entwickler haben oft schon vor dem Entwurf ein grobes Gefühl für die zu erwartende Performance

    • Auch ich habe in den meisten Fällen Bottlenecks zutreffend vorhergesagt. Ich habe meinen Ansatz auch oft nach vorab durchgeführten Performance-Tests geändert
    • Aber nach 30 Jahren Erfahrung gilt für mich: Das Gefühl, dass ein Bottleneck auftreten wird, stimmt oft, aber der genaue Ort und Zeitpunkt lassen sich nicht vorhersagen
    • Es gab auch den Witz „Was soll Rob Pike schon wissen“, aber er ist die Person hinter Unix und Go. Für seine Regeln gibt es einen Grund