14 Punkte von GN⁺ 2025-06-26 | 1 Kommentare | Auf WhatsApp teilen
  • 1982 führte das Lisa-Softwareteam von Apple eine Richtlinie ein, nach der zur Veröffentlichung der Software die wöchentliche Anzahl der Codezeilen jedes Entwicklers erfasst wurde
  • Bill Atkinson vertrat die Ansicht, dass die Anzahl der Codezeilen ein falscher Maßstab für Softwareproduktivität sei
  • Er schrieb die Region-Berechnungs-Engine von Quickdraw vollständig neu, reduzierte dabei den Code um etwa 2.000 Zeilen und steigerte die Leistung um das Sechsfache
  • Atkinson trug in das Verwaltungsformular zur Meldung der Codezeilen -2000 ein
  • Schließlich verlangten die Manager von Bill nicht mehr, das Formular einzureichen

Das Lisa-Softwareteam von 1982 und die Richtlinie zur Erfassung von Codezeilen

  • Anfang 1982 begann das Lisa-Softwareteam, sich mit dem Ziel auf die Veröffentlichung der Software innerhalb der nächsten sechs Monate zu konzentrieren
  • Einige Manager kamen zu dem Schluss, dass es den Fortschritt fördern würde, die Anzahl der Codezeilen zu verfolgen, die jeder Ingenieur pro Woche schrieb
  • Dafür wurde ein Formular eingeführt, in das die Ingenieure jeden Freitag die Zahl der von ihnen geschriebenen Codezeilen eintrugen und einreichten

Bill Atkinsons Sicht auf Produktivitätsmaßstäbe

  • Bill Atkinson, der Quickdraw und die Benutzeroberfläche entwarf, war der Meinung, dass die Anzahl der Codezeilen kein Maßstab für Softwareproduktivität sein könne
  • Er betonte, dass das Ziel darin bestehe, Programme so klein und schnell wie möglich zu machen
  • Ihm war bewusst, dass die Messung nach Codezeilen im Gegenteil unsaubere und ineffiziente Software begünstigen könnte

Refactoring und Optimierung der Quickdraw-Region-Engine

  • Atkinson hatte vor Kurzem die Region-Berechnungs-Engine von Quickdraw mit einem einfacheren und allgemeineren Algorithmus vollständig neu geschrieben
  • Das Ergebnis der Optimierung war eine bis zu sechsfache Beschleunigung der Region-Operationen
  • Dabei verringerte sich ganz natürlich auch der Code um 2.000 Zeilen

Der Bericht über -2000 Codezeilen und die Reaktion des Managements

  • Als Atkinson in der ersten Woche das Verwaltungsformular ausfüllte, schrieb er in das Feld für die Anzahl der Codezeilen -2000
  • Wie die Manager auf diese Zahl reagierten, ist nicht genau bekannt
  • Einige Wochen später wurde Bill gebeten, das Formular nicht mehr einzureichen, was er mit Freude aufnahm

1 Kommentare

 
GN⁺ 2025-06-26
Hacker-News-Kommentare
  • Der beste Commit, an den ich mich erinnere, war die Löschung von etwa 60.000 Zeilen Code und der Ersatz eines kompletten „Servers“, der seinen gesamten Zustand im Speicher hielt, durch rund 5.000 Zeilen leichte Logik

    • Ich halte das für eine algorithmische Meisterleistung, weil dieser Code leicht genug war, um sich nahtlos in andere Services zu integrieren, und keinen Speicherzustand mehr benötigte
    • Ich fand heraus, dass sich ein geführtes Subgraph-Isomorphieproblem für einen bestimmten Baum lösen ließ; dadurch konnte ich bei einem einzigen Durchlauf durch einen allgemeinen gerichteten multigraphen nur mit einem kleinen Stack die Pfade vom Start-Root verfolgen und so den Ausgabegraphen (Baum) erzeugen
    • Der „-60.000-Zeilen-Commit“ war wirklich ein unvergesslicher Moment, und seither habe ich leider nichts mehr getan, das algorithmisch ähnlich beeindruckend war
      • Ich bin ein Hobbyprogrammierer, der im Arbeitsumfeld viel skriptet und sich in einigen Teilen des Programmierens ziemlich fit fühlt, aber solche Geschichten erinnern mich immer wieder demütig daran, wie groß die Welt dessen ist, was ich nicht weiß, und dass selbst ein ganzes Leben zum Lernen kaum ausreicht
      • Ich würde gern mehr Kontext hören. Ein zustandsbehaftetes Programm zustandslos zu machen wirkt wie Magie, und ich würde das unbedingt lernen wollen
      • Ich bin Mathematiker mit Hintergrund in Graphentheorie und Algorithmen und frage mich, ob sich meine Fähigkeiten auf solche reale Arbeit anwenden lassen. Könntest du vielleicht mehr Details teilen?
      • Dass der Zielgraph ein Baum ist, scheint mir nicht besonders wichtig zu sein. Der eigentliche Punkt ist wohl der „geführte“ Teil, der den einzelnen Durchlauf ermöglicht
        • Man geht davon aus, dass beim Start an einem bestimmten Knoten im Ursprungsgraphen der Root des Zielbaums bei Existenz einer Isomorphie ebenfalls genau diesem Knoten entsprechen muss
        • Man kann das Problem so interpretieren, dass man den Ursprungsgraphen entlang des Musters des Zielbaums durchläuft und bei einer Nichtübereinstimmung false, bei vollständiger Übereinstimmung true erhält. Daraus lässt sich schließen, dass dieser Ansatz auch auf beliebige Subgraphen anwendbar ist, solange der Startpunkt eindeutig festgelegt ist
      • Der Witz, dass vielleicht genau solche Programmierer die Urheber von Coding-Interview-Aufgaben wie „drehe einen Binärbaum um“ sind
        • Bitte eine einfache Erklärung für normale Entwickler, die sich für Graphentheorie interessieren, aber die Terminologie schwierig finden
  • Während des Studiums arbeitete ich für ein Unternehmen mit der Management-Politik, dass schon Studienanfänger guten Code schreiben könnten; am Ende waren sie ein nicht bewiesenes Gegenbeispiel

    • Ich hatte einen Bug im Code behoben, aber derselbe Bug tauchte weiter auf. Bei der Analyse stellte sich heraus, dass statt Parameter zu bestehenden Funktionen hinzuzufügen einfach Kopien erstellt und nur leicht verändert wurden. Am Ende habe ich über drei Viertel der Codebasis gelöscht, mehrere tausend Zeilen Turbo Pascal
    • Der Kunde des Projekts war die Energy-Abteilung, und es ging um ein Programm zur Verwaltung von Kernmaterialbeständen — ich erinnere mich an schlaflose Nächte
      • Als satirischer Vorteil des bestehenden Copy-and-Paste-Codes wurde genannt, dass man die Stabilität des alten Codes nicht gefährdet und zugleich auch noch die „Beitrags“-Metrik des Managers bedient. Zum Revert müsse man ja nur die Kopie löschen
      • Wir haben auch so einen Kollegen im Team, der oft Code dupliziert. Ich vermute, das ist eine Gewohnheit, um unter Zeitdruck oder für lautstarke Stakeholder schnell Ergebnisse zu liefern. Das eigentliche Problem ist, dass man die notwendige Zeit für das Refactoring gemeinsamer Funktionen und ausreichende Tests nicht investieren will
      • Auch externe Entwickler, mit denen ich früher gearbeitet habe, zeigten eine ähnliche Gewohnheit. Als ich darauf hinwies, dass das zu Verwirrung führen könne, bekam ich die Antwort: „Dann benutzt man eben Ctrl+F“
      • Die Frage, ob sich der geschilderte Fall vielleicht in der Region Blacksburg abgespielt hat
      • Ich hatte eine ähnliche Erfahrung in einem Unternehmen, das nahezu identische Portale für mehrere Länder in Südostasien betrieb. Der Quellcode jedes Portals lag in einem eigenen Git-Repository, und jede Funktion oder Bugfix, die für alle Portale gelten sollte, musste mühsam manuell in mehrere Codekopien zurückportiert werden
        • Ich fragte, ob man nicht alles in ein einziges Repository legen und portalspezifische Anpassungen per Feature-Flag steuern könne, bekam aber gesagt, das sei nicht möglich
        • Am Ende habe ich innerhalb von zwei bis drei Monaten den Code von vier bis fünf Portalen in ein Repository zusammengeführt, Feature-Flags und Framework-Upgrades eingeführt und das Ganze sauber ausgerollt. Seitdem lassen sich Bugs in allen Portalen gleichzeitig beheben — eine enorme Befreiung von dieser endlosen Handarbeit
  • Zu dem Thema hat jemand beliebte Hacker-News-Threads über „-2000 Zeilen Code“ gesammelt, zum Beispiel in diesem Link

    • Es wird darauf hingewiesen, dass das regelmäßige Reposten alter Meisterwerke eine nützliche Tradition ist, sowohl für neue als auch für alte Nutzer
      • Ich bin ein einfacher Mensch: Bei „-2k lines of code“ stimme ich automatisch hoch
        • Gegenüber Kunden, die Produktivität als eindimensionale Metrik verwalten wollen, erzähle ich oft die Geschichte von Atkinson. Der wahre Maßstab für Produktivität sollte Nützlichkeit sein; wenn man die wirklich quantifizieren könnte, wäre man wohl Kandidat für den Wirtschaftsnobelpreis
  • Mein Web-UI-Projekt hatte 250.000 Zeilen Code, ohne Backend

    • Der vorherige Entwickler war klug, aber neu in JS, speicherte den gesamten Zustand in benutzerdefinierten Attributen des DOM und pflasterte alles mit addEventListener zu. Ich machte den Witz, das sei der Code, der herauskomme, wenn man einem Mönch ein JavaScript-Buch und zehn Jahre Einzelhaft gibt
    • Über einige Monate hinweg wandelte ich die Struktur in Web Components um und entfernte 50.000 Zeilen. Danach begann ich mit einer vollständigen Neuschreibung; aktuell bin ich bei etwa 80 % derselben Funktionalität, aber der gesamte Code liegt bei schlanken 17.000 Zeilen, Bibliotheken wie Vue/pinia nicht mitgerechnet
    • Bald werde ich mehr als 200.000 Zeilen gelöscht haben; ich bezweifle, dass ich je wieder etwas Vergleichbares erleben werde — fast ein Grund, in Rente zu gehen
      • Ich hatte eine ähnliche Erfahrung. Der ursprüngliche Autor war praktisch noch Junior, zugleich aber Gründer des Unternehmens und extrem produktiv. Da ihm Erfahrung mit Teamarbeit und Zusammenarbeit an fremdem Code fehlte, steckte die Struktur voller denkbarer Code-Smells
        • Funktionen mit mehreren tausend Zeilen, zehn Ebenen verschachtelter switch/case/if/else/Ternary-Operatoren, vermischte SQL-Statements und JS/HTML/HTML mit eingebettetem JS, keinerlei automatisierte Tests — so sah dieses Frontend aus der PHP-/Dojo-Ära aus
      • Der Hinweis auf „leichteren Code mit nur 80 % der Funktionalität“ zeigt schon die Schwäche solcher Vergleiche: Wenn nur ein Teil der ursprünglichen Features implementiert ist, braucht man natürlich auch nicht so viele Zeilen wie zuvor
  • Es gibt einen Dilbert-Comic mit einer Struktur unbegrenzter Belohnung: Dilberts Chef verspricht eine Geldprämie für jeden behobenen Bug, worauf Wally sagt: „Heute werde ich wohl mindestens einen Minivan voll codieren!“

    • Solche Situationen nennt man „Perverse incentive“, erklärt in diesem Referenzlink
    • Mein Manager hatte diesen Comic ( Bild ) ebenfalls an die Wand im Pausenraum gehängt
    • Jemand fragt ganz praktisch, was mit „Minivan“ gemeint sei
  • Es wird ein reales Beispiel aus dem dotnet/runtime-Repository geteilt, bei dem 64.000 Zeilen gelöscht wurden

    • Die eingebaute Unterstützung für C# + WinRT-Interop wurde durch ein Tool zur Codegenerierung ersetzt; dafür war eine entschlossene, klare Umstellung in einem Zug nötig. Siehe PR-Link
  • Immer wenn ich Statistiken darüber sehe, wie stark LLMs die Produktivität von Entwicklern gesteigert haben sollen, denke ich an diese klassische Geschichte

    • Als Gegenargument kommt, dass KI auch ziemlich gut darin ist, Code zu löschen, und dazu wird ein lustiger Fall aus der Cursor-Community geteilt, in dem „die KI alles gelöscht hat“
    • Heutzutage ist „X % unseres neuen Codes werden von KI geschrieben!“ ein beliebter Werbeslogan der Branche
    • Wenn man sogar die Kosten für Bau und Wartung neuer Kernkraftwerke einrechnen würde, merkt man erst, wie unrealistisch übertrieben solche Produktivitätszahlen sind
  • Ich habe keinen CS-Abschluss und arbeite mit Wissen, das ich mir in der Praxis angeeignet habe

    • Bei unserem Projekt geht es darum, lebende Objekte in eine für Menschen lesbare Form umzustrukturieren
      • Die endgültige Darstellung erfordert viele sehr komplexe Typen, während die Ausgangsdarstellung vergleichsweise einfach ist
      • Wenn es ähnliche Datenknoten gibt, müssen sie verglichen und zusammengeführt werden — also im Grunde in Methoden extrahiert und mit passenden Parametern versehen —, um die Lesbarkeit zu verbessern
        • Anfangs wandelten wir zuerst in die Endtypen um und verglichen dann. Dadurch explodierte die Zahl der Typkombinationen und wurde fast unbeherrschbar; nach einigen Jahren war eine Komplexität erreicht, bei der selbst Ingenieure die Struktur nicht mehr verstanden
      • Später lernte ich einen hashmap-basierten Ansatz kennen: Knoten mit demselben Grundgerüst werden über Hashwerte unterschieden, verglichen und zusammengeführt und erst danach in die Endtypen umgewandelt — also eine zweistufige Struktur
      • Durch den Wechsel von einer typenorientierten zu einer datenorientierten Abstraktion ließen sich sogar merkwürdige Klassenhierarchien leicht als einfache Eigenschaften verwalten
      • Kurz gesagt: eine dumme mehrstufige Dekompiler-Struktur, aber mit deutlich besserer Verarbeitungsgeschwindigkeit und Lesbarkeit. Es gibt je nach Situation keine Wunderwaffe, aber bei uns waren die „Typen“ das Kernproblem, und dieser Lösungsansatz half dem Projekt enorm
  • Vor der Jahresendbeurteilung sah ich in unseren internen Statistiken zum monolithischen Repository, dass ich netto zu den Leuten mit negativem Codebeitrag gehörte

    • Das lag daran, dass ich automatisch generierten API-Code und Typen entfernt und alte API-Versionen ausgemustert hatte, aber es fühlte sich auf seltsame Weise erfreulich an, jeden Tag zur Arbeit zu kommen und einfach Code zu löschen
  • Vor langer Zeit war ich schockiert über einen erbärmlichen KPI-Fall in einem großen Projekt, in dem PLs die Bugzahlen pro Entwickler — behobene und verursachte Bugs — offline von Hand erfassten und an die Wand hängten

    • Ich war nur in einem verbundenen Projekt und blieb davon verschont, aber ein Kollege ließ sich von einer Anekdote über den Regisseur Lars von Trier inspirieren, der aus der bürokratischen „Autorenliste“ gestrichen wurde, nachdem er aus der dänischen Flagge den Kreuzteil ausgeschnitten und als rote kommunistische Flagge wieder zusammengenäht zurückgegeben hatte. Mein Kollege schnitt daraufhin seine Zeile mit dem Bug-Count aus der Liste heraus, klebte sie wieder ein und protestierte so öffentlich. Am nächsten Tag verschwand diese Liste für immer — eine wertvolle Erinnerung für mich
      • „Weil ich nicht auf dieser Liste stehen will!“ war die einfache und direkte Antwort des Kollegen, die die ganze Situation treffend zusammenfasst
      • Dazu kommt noch die ganz praktische Schwierigkeit, sich vorzustellen, wie Flagge und Liste visuell genau aussahen