1 Punkte von GN⁺ 2023-12-30 | 1 Kommentare | Auf WhatsApp teilen
  • incident.io nutzte zur Entscheidung, ob Entwickler-Laptops auf M3 umgestellt werden sollen, nicht das Bauchgefühl, sondern Go-Build-Zeiten, und sammelte reale Daten aus den lokalen Entwicklungs-Feedback-Loops
  • Da sich mit bestehenden Go-Hot-Reloaders die benötigten Werte nur schwer erfassen ließen, baute das Team ein eigenes Tool und lud Build-Events wie Plattform, Arbeitsspeicher, Stromversorgung, Build-Phasen, auslösende Datei und Gesamtdauer in das Data Warehouse
  • Aus rund 25k Builds wurden fehlgeschlagene, abgebrochene und im Batteriebetrieb ausgeführte Builds herausgefiltert; analysiert wurden 12.525 erfolgreiche Builds, wobei sich ein statistisch signifikanter Unterschied zeigte: Builds am Netzstrom waren schneller als im Batteriebetrieb
  • Das Ergebnis: Nutzer von M1-Geräten warteten bis zum Abschluss eines Builds oft fast 2 Minuten, M2 brachte gegenüber M1 eine große Verbesserung, und M3 zeigte gegenüber M2 eine schrittweise Verbesserung
  • Beim gesamten Build zeigte sich kein klarer Unterschied durch den Arbeitsspeicher, aber bei der Linker-Zeit waren Geräte mit 32–36 GB im Vorteil, weshalb incident.io entschied, M1-Geräte durch M3 Pro mit standardmäßig 36 GB zu ersetzen

Das Entscheidungskriterium für ein Upgrade ist der Entwicklungs-Feedback-Loop

  • Alle Entwickler bei incident.io verwenden MacBooks für ihre Entwicklungsarbeit
  • Nachdem Apple im Oktober 2023 das M3 MacBook Pro vorgestellt hatte, sagte CTO Pete, dass ein Austausch erfolgen würde, wenn sich der Nutzen des Upgrades mit Daten belegen ließe
  • Um zu entscheiden, ob auf M3 upgegradet werden soll, bereitete das Team drei Dinge vor
    • einen benutzerdefinierten Go-Hot-Reload­er
    • die Erfassung von Build-Telemetrie auf den Entwickler-Laptops
    • Datenanalyse mit dem neuesten Modell von OpenAI und dem Code Interpreter
  • Die Produktivität von Entwicklern direkt zu quantifizieren ist schwierig, aber incident.io sieht schnelle Feedback-Loops als wichtig für die Effizienz von Entwicklern an
  • In der lokalen Entwicklung wiederholen sich häufig folgende Feedback-Loops
    • Kompilieren des Go-Monolithen
    • Code-Generierung für API-Clients und Interfaces
    • Hot Reload von Frontend- und Mobile-Apps
  • Entwickler bei incident.io führen die gesamte incident.io-Umgebung lokal auf ihren Laptops aus und halten den Feedback-Loop von Code-Änderung bis zur Ausführung bei unter 30 Sekunden
  • Die Go-Anwendung nähert sich einer Codebasis von fast 1 Million Zeilen, daher wurde das häufig auftretende und kostspielige Go-Kompilieren als Vergleichsmaßstab für die MacBook-Leistung gewählt

So wurde die Build-Telemetrie erfasst

  • incident.io verwendet seit der Erstellung des ursprünglichen GitHub-Repositories codegangsta/gin als Go-Hot-Reload­er
  • Es wurden auch alternative Hot-Reload­er geprüft, aber kein Tool gefunden, das die für die Analyse der Build-Zeiten nötige Telemetrie bereitstellt
  • Für jeden Build sollten folgende Daten erfasst werden
    • Systemebene: Plattform M1/M2/M3, gesamter Arbeitsspeicher usw.
    • Laufzeitmetriken: Betriebssystem, Speichernutzung, Stromquelle, Batteriestand usw.
    • Build-Telemetrie: Gesamtdauer, Phasen des Go-Builds, Datei, die den Build ausgelöst hat, usw.
  • Da es keine passende Alternative gab, baute das Team ein eigenes Tool, beginnend bei main.go, und extrahierte die benötigten Werte durch Ausführen und Parsen der Ausgaben verschiedener Mac-Binaries
    • memory_pressure
    • docker
    • sysctl
    • pmset
  • Der zugehörige Code wurde als Gist veröffentlicht
  • Nachdem Sammler für System- und Laufzeitdaten erstellt worden waren, wurde der Go-Build-Befehl umhüllt, um Zeiten für einzelne Phasen wie Linker und Compiler sowie die Build-auslösende Datei zu erfassen
  • Der finale Hot-Reload­er wurde über das bestehende Ziel make run ausgeführt und war für das Engineering-Team eine unsichtbare Änderung
  • Nach jedem abgeschlossenen Build wurde ein Telemetrie-Event an einen HTTP-Endpunkt gesendet und über einen Fivetran-Webhook-Empfänger in das Data Warehouse geladen

Analyseablauf mit OpenAI Assistant

  • Nachdem über mehrere Wochen ein ausreichend großer Datensatz aufgebaut worden war, wurde aus BigQuery das Ergebnis von select * except(payload) from developer__build_events als CSV exportiert
  • OpenAI Assistants wurden ein Prompt mit Zielbeschreibung und die CSV-Datei bereitgestellt
  • Das experimentelle Modell gpt-4-1106-preview wurde zusammen mit dem Code Interpreter für die Datenanalyse verwendet
  • Build-Zeiten schwanken selbst auf demselben System stark, und auch der Cache-Effekt des Go-Compilers ist groß, sodass ein bloßer Vergleich der Durchschnittswerte pro Plattform nicht fair wäre
    • Ein M3 Max ohne Cache kann langsamer sein als ein älteres Intel MacBook mit vorhandenem Cache
  • Die Analyse basierte daher nicht auf einem einfachen Mittelwertvergleich, sondern darauf, die Build-Bedingungen zu ordnen und Plattform, Arbeitsspeicher und Stromzustand getrennt zu betrachten

Datenbereinigung und faire Vergleichsbedingungen

  • Der gesamte Datensatz umfasste etwa 25k Builds und wurde zu verschiedenen Tageszeiten, auf unterschiedlichen Laptops und unter verschiedenen Bedingungen erfasst
  • Für einen fairen Plattformvergleich wurden folgende Builds ausgeschlossen
    • fehlgeschlagene oder abgebrochene Builds: Da diese nicht abgeschlossen wurden, eignen sie sich nicht für den Vergleich der Build-Geschwindigkeit
    • Builds im Batteriebetrieb: OS X kann zur Schonung der Akkulaufzeit die Leistung drosseln
  • Nach Ausschluss der fehlgeschlagenen Builds wurden 12.525 erfolgreiche Builds gezählt
  • Der Leistungsunterschied zwischen Netzstrom- und Batteriebetrieb wurde vor allem anhand von M1 Pro und M2 Max verglichen
  • In statistischen Tests lag die durchschnittliche Build-Zeit bei Netzstrom niedriger; der p-Wert lag bei etwa 0,0014
  • Für die weitere Analyse wurden danach nur noch erfolgreiche Builds am Netzstrom verwendet

Warum Go-Build-Zeiten schwanken

  • Der Go-Monolith von incident.io ist ein Objekt fortlaufender Beobachtung der Build-Performance, und neben Hardware-Käufen ist auch das Entfernen oder Tuning des Build-Prozesses selbst wichtig
  • Go-Projekte bestehen aus mehreren Paketen, und der Go-Compiler nutzt Caching, damit nur Pakete neu kompiliert werden, bei denen Änderungen erkannt wurden
  • Die incident.io-App ist so entworfen, dass sie einen breiten Abhängigkeitsgraphen und wenige grundlegende Module hat, sodass die meisten Änderungen nicht zur Neukompilierung des gesamten Graphen führen
  • Build-Typen lassen sich grob in vier Klassen einteilen
    • sofort fertig, unter 3 Sekunden: Änderungen ohne Bezug zum Go-Compiler, sodass das gecachte Binary genutzt werden kann
    • schneller Build, unter 30 Sekunden: Änderung an einem einzelnen Paket mit wenigen abhängigen Paketen; der Cache wird weitgehend wiederverwendet, die Zeit fließt meist ins Linken
    • mittlerer Build, 30 Sekunden bis 1 Minute: Ein Feature-Paket mit einigen abhängigen Unterpaketen wurde geändert, aber der Großteil bleibt wiederverwendbar
    • langsamer Build, über 1 Minute: Ein Typ wurde dem grundlegenden Paket domain hinzugefügt, sodass alle Pakete der Anwendung neu kompiliert werden müssen
  • Ein Plattformvergleich muss diese unterschiedlichen Build-Charakteristika berücksichtigen; alle Builds zusammenzuwerfen wäre ein Vergleich von Äpfeln mit Birnen

Vergleich von M1, M2 und M3

  • Zunächst wurden nur erfolgreiche Builds am Netzstrom betrachtet und M1 Pro und M2 Max verglichen
  • M2 Max war beim Build-Tempo deutlich schneller als M1 Pro, doch die beiden Geräte unterschieden sich nicht nur beim Chipsatz, sondern auch bei der Speicherkonfiguration
  • Die Verteilung erfolgreicher Build-Events nach Plattform und Speicher war wie folgt
    • Apple M1 Pro 16GB: 5.235
    • Apple M2 Pro 16GB: 1.927
    • Apple M2 Max 32GB: 3.842
    • Apple M3 Pro 18GB: 321
    • Apple M3 Pro 36GB: 899
    • Apple M3 Max 36GB: 301
  • Der Vergleich zwischen M1 Pro 16GB und M2 Max 32GB war wegen des Speicherunterschieds nicht vollständig fair
  • Beim Vergleich von M2 Pro 16GB und M2 Max 32GB schien der Einfluss von 32 GB Arbeitsspeicher auf die gesamte Build-Zeit gering zu sein
  • M2 Pro und M2 Max sind im Wesentlichen derselbe Chip; Max verfügt zusätzlich über zwei energieeffiziente Kerne mehr
    • Diese Kerne leisten etwa 1/5 eines Performance-Kerns und tragen nach Einschätzung des Teams wenig zum Kompilieren von Go-Programmen bei
  • Für die Bewertung von M3 wurden die folgenden drei Geräte gekauft
    • M3 Pro 12-Core, 6 Performance-Kerne + 6 energieeffiziente Kerne, 18GB
    • M3 Pro 12-Core, 6 Performance-Kerne + 6 energieeffiziente Kerne, 36GB
    • M3 Max 14-Core, 10 Performance-Kerne + 4 energieeffiziente Kerne, 36GB
  • Die Build-Zeit-Diagramme von M3 Pro 18GB und 36GB sahen ähnlich aus, allerdings gab es für M3 weniger Daten als für andere Plattformen
  • Beim Vergleich von M3 Pro und M3 Max unter Ausschluss sehr schneller Builds unter 3 Sekunden zeigte M3 Max keine so deutliche Verbesserung, dass sich der 60 % höhere Preis gegenüber dem Basismodell M3 Pro rechtfertigen ließe
  • Das Gesamturteil lautete wie folgt
    • Nutzer von M1-Laptops warten bis zum Abschluss eines Builds oft fast 2 Minuten
    • M2 ist gegenüber M1 ein großes Upgrade
    • M3 ist gegenüber M2 eine schrittweise Verbesserung
    • Nutzer von M1-Geräten werden auf das Basismodell M3 Pro upgegradet
    • Nutzer von M2-Geräten brauchen kein Upgrade

Arbeitsspeicher zeigt sich deutlicher bei der Linker-Zeit

  • Beim Vergleich der gesamten Build-Zeit zeigte sich kein großer signifikanter Unterschied, wenn von 16–18GB auf 32–36GB erhöht wurde
  • Entgegen den Erwartungen war der Speichereffekt in den Diagrammen nicht deutlich zu sehen, daher wurde innerhalb der Build-Phasen die Linker-Zeit separat analysiert
  • Die Telemetrie-Events enthielten Zeiten für die Link- und Compile-Phasen, und aus build_stages.link.duration_seconds wurde zur Analyse die Spalte linker_time erzeugt
  • Beim Vergleich von linker_time nach Plattform- und Speicherkonfiguration zeigte sich ein anderes Muster
    • M1-, M2- und M3-Geräte mit 32–36GB Arbeitsspeicher schlossen das Linken fast immer in unter 20 Sekunden ab
    • Geräte mit 18GB oder weniger benötigten fürs Linken häufig mehr als 20 Sekunden
  • Mehr Speicher erwies sich somit zwar beim gesamten Build als weniger klar, in der Linker-Phase jedoch als nützlich
  • Auch die Entfernung von Docker von Entwicklungsmaschinen wird geprüft; bei Geräten mit wenig Speicher könnte mehr verfügbarer Systemspeicher ohne Docker die Linker-Zeit verbessern
  • In der Mobile-App-Entwicklung nutzen Simulatoren viel Systemspeicher, daher wurde zusätzlicher Arbeitsspeicher auch als sinnvolle Zukunftsinvestition bewertet

Endgültige Entscheidung und Nebeneffekte

  • incident.io entschied, M1-Geräte auf das Basismodell M3 Pro mit 36GB Arbeitsspeicher upzugraden
  • M2-Geräte werden vorerst nicht upgegradet, da ihre Leistung bereits ausreichend gut erscheint
  • Über die Kaufentscheidung für Laptops hinaus wuchs auch das Verständnis für Entwicklungsumgebung und Werkzeuge
  • Das Team zog folgende Erkenntnisse
    • Go-Build-Zeiten sind ein guter Benchmark zur Messung der Leistung von Entwickler-Maschinen
    • Ein eigener Go-Hot-Reload­er zur Erfassung der nötigen Metriken wurde gebaut und brachte auch weitere Verbesserungen bei der Nutzbarkeit
    • Das Team versteht besser, welche Faktoren Go-Builds schneller oder langsamer machen
    • Mit OpenAI Assistants lassen sich ähnliche Probleme der Datenanalyse bearbeiten
    • Die Verbesserungen in Apples Chip-Line-up konnten aus Sicht von Go-Entwicklern quantifiziert werden
    • Arbeitsspeicher ist wichtig, zeigt sich aber deutlicher bei der Linker-Zeit als bei der gesamten Build-Zeit

1 Kommentare

 
GN⁺ 2023-12-30
Meinungen auf Hacker News
  • Ein großartiger Artikel, und mir gefällt auch, wie vielfältig die Daten erhoben und analysiert wurden. Trotzdem wäre es wohl viel einfacher und genauer gewesen, die jeweiligen Notebooks nebeneinanderzustellen und im gleichen Szenario zeitgemessene Builds laufen zu lassen.
    Man hätte ein paar Fälle vergleichen können, etwa einen vollständigen Build, einen inkrementellen Build mit den jüngsten Änderungen oder einen inkrementellen Build, bei dem ein bestimmtes Modul neu gebaut werden muss. Oder man hätte vermutlich innerhalb eines Tages ein Skript schreiben können, das die letzten 100 Git-Commits der Reihe nach anwendet und jeweils die inkrementelle Build-Zeit misst.
    Wenn man unternehmensweite Statistiken sammelt, kann eine starke Verzerrung entstehen. Zum Beispiel verwenden neue Mitarbeiter eher ein M3, langjährige Mitarbeiter eher ein M1; neue Mitarbeiter machen häufiger kleine Änderungen, während erfahrene Entwickler tiefer im Code oder in komplexeren Bereichen arbeiten, was die Build-Zeiten verlängern kann.
    Daher ist die Analyse an sich zwar beeindruckend, aber angesichts der im Sample angelegten Verzerrungen hätte man meiner Meinung nach mit einem einfachen Ansatz beginnen sollen: die jüngsten Commits auf den jeweiligen Notebooks benchmarken, bevor man eine unternehmensweite Architektur zur Datenerfassung baut.

    • Ich stimme dem Vorschlag vollkommen zu, und als Autor des Artikels habe ich zuerst die Performance einiger häufiger Aufgaben stichprobenartig geprüft.
      Der Grund für das Sammeln dieser Daten war nicht nur der Vergleich zwischen Geräten, sondern auch, historische Daten zu Entwickler-Build-Zeiten aufzubauen, die Build-Performance kontinuierlich zu messen und Regressionen zu erkennen.
      Wenn wir sehen, dass die Build-Zeiten steigen, passen wir häufig die Struktur der Codebase an, um Builds schneller zu machen.
    • Eine Analyse von Netzwerk-Builds als Alternative zum M3 habe ich nicht gesehen. Mein Projekt hat rund 40 Millionen Zeilen Code, und ab einem gewissen Punkt kann eine lokale Maschine, egal wie schnell sie ist, nicht mehr mit den vom Infrastrukturteam gebauten Netzwerk-Builds mithalten.
      Ein M3 kann Builds vielleicht 30 % schneller ausführen als ein M1, aber Netzwerk-Builds sind 15-mal schneller. Man könnte also prüfen, ob man statt M3-Geräte an Entwickler auszugeben besser in Netzwerk-Builds hätte investieren sollen.
    • Die Verzerrung des Samples ist ein Problem der Analysemethodik. Das zeigt, dass man sich nicht auf einen KI-Assistenten verlassen kann, wenn man selbst in dem Thema nicht ausreichend sattelfest ist.
      Es wurde ein t-Test auf Daten angewendet, die nicht unabhängig gesampelt wurden: Mehrere Datenpunkte kamen von unterschiedlichen Personen, und da jede Person andere Aufgaben hat, kann auch der Rechenaufwand variieren, was Störfaktoren erzeugt. Das verletzt die Grundannahmen des t-Tests, wurde vom Code Interpreter aber nicht angemerkt.
      Stattdessen hätte man ein lineares gemischtes Effektmodell verwenden können, mit Faktoren wie Notebook-Besitzer und Betriebszugehörigkeit als zufällige Effekte.
      Trotzdem sind die Daten selbst interessant, besonders der RAM-Teil war spannend. Caches sind mächtig, und mehr RAM bringt größere Vorteile, als viele denken. Bei einem MacBook mit mehr RAM als normalerweise nötig wird der Großteil des freien RAMs als Cache gefüllt.
    • Aus irgendeinem Grund wirkt es so, als sei für die Beantwortung der Frage die möglichst teure Methode gewählt worden. Außerdem wurde festgestellt, dass auch ein M2 ausreicht; warum die Schlussfolgerung dann war, M1-Nutzer auf das teurere M3 upzugraden, erschließt sich mir ebenfalls nicht.
    • Es wäre wohl gut gewesen, festzuhalten, was genau wie gebaut wurde, etwa nach dem Muster „Repository startet bei diesem Commit“, „diesen Diff anwenden“, „Build mit diesem Befehl ausführen“.
      Wenn man das etwa eine Woche lang sammelt, bekommt man einen Querschnitt der realen Workloads, kann diese Builds auf jeder Hardware-Klasse wiederholt ausführen und sie später auch für neue Hardware wiederverwenden.
  • Als Wissenschaftler finde ich interessant, wie Computerprogrammierer mit Daten umgehen.
    Es wurden hübsche Diagramme erstellt, die Analyse mit ChatGPT sehr schnell automatisiert, und ChatGPT hat einen recht plausiblen t-Test geliefert.
    Es gab aber Schwankungen nach Speicher und Chip-Typ, ohne dass an lineare Regression gedacht wurde, und es wurden Histogramme gezeichnet, die schwer zu vergleichen sind. Man hätte einfache Mittelwerte und Fehlerbalken ergänzen oder kumulative Verteilungsfunktionen (CDFs) verwenden können, bei denen Überlappungen oder Verschiebungen leichter zu erkennen sind.

    • Als Informatikforscher hatte ich dieselbe Reaktion. Im Bachelor habe ich wegen meines Doppelstudiums Biologie/Informatik Statistik gehört, aber ich glaube, kumulative Verteilungsfunktionen habe ich erst in der Graduiertenschule für Datenanalysen verwendet.
    • Normalerweise ist das die Aufgabe eines Data Scientist, und die meisten Engineering-Infrastrukturteams haben keinen Data Scientist; meistens brauchen sie auch keinen.
      Üblicherweise geht man mit Daten so um, wie die Tools sie darstellen, und das hängt stark mit Analyse-, Performance-Analyse- und Observability-Softwarepaketen zusammen.
      Von einem durchschnittlichen Software Engineer zu erwarten, dass er CDFs kennt, ist ungefähr so, als würde man erwarten, dass er Quaternionen in 3D-Grafik oder die Grundlagen des Shader-Schreibens kennt.
    • Die Verteilung scheint definitiv nicht normalverteilt zu sein, und auch die Differenz der Mediane hätte ziemlich wichtig sein können. Als ersten Ansatz hätte ich wohl den Wilcoxon-Test verwendet.
      Alternativ wäre auch Quantilregression möglich. Wenn die Hypothese M3 > M2 > M1 lautet, hätte der bekannte Jonckheere–Terpstra-Test für geordnete Mediane für diese Pseudoanalyse genau gepasst.
    • An einigen Stellen wurden Boxplots verwendet, die einen klareren Vergleich ermöglichen. Es wäre wohl effektiver gewesen, alle Daten als Boxplots zu zeigen.
    • Für solche Vergleiche würde ich Diagramme der empirischen kumulativen Verteilungsfunktion empfehlen. Jede Verteilung wird zu einer Kurve, und mehrere Kurven lassen sich im selben Diagramm leicht vergleichen.
      Ein Beispiel findet sich im letzten Diagramm auf dieser Seite: https://ggplot2.tidyverse.org/reference/stat_ecdf.html
  • Eine solide Analyse, aber aus persönlicher Erfahrung möchte ich eine Warnung aussprechen.
    Bei einem mittelgroßen Softwareunternehmen mit 2.000 Mitarbeitenden wollten wir die Entwicklerproduktivität steigern und prüften, statt neuer Notebooks den Entwicklungs-Stack auf AWS-Instanzen zu verlagern.
    Am Ende wurde daraus ein mehrjähriges Projekt, an dem etwa vier Entwickler in Vollzeit arbeiteten, und rückblickend hat sich der Nutzen im Verhältnis zu den Kosten nicht gelohnt. Eine vollständig lokale Development Experience in der Cloud nachzubilden, ist immer noch viel zu schwierig.
    Deshalb denke ich, dass es besser ist, die Notebooks aufzurüsten.

    • Unser Team entwickelt seit Jahren gegen einen vollständig remote laufenden K8s-Cluster, und das bietet eine ziemlich starke Developer Experience.
      Der Code liegt auf dem Notebook, wird aber ohne Docker-Builds oder K8s-Deployments in Echtzeit mit Remote-Services synchronisiert und fühlt sich wirklich lokal an.
      Besonders hilfreich ist, dass man beim Coden sofort Integrationstests und mehr ausführen kann und so den commit-push-pray-Zyklus vermeidet.
      Dafür nutzen wir Garden (https://docs.garden.io). Ob mit Garden oder ohne: Mit den richtigen Tools kann es ziemlich großartig sein, die Power der Cloud für den inneren Entwicklungs-Loop zu nutzen.
      Ein Text mit mehr Erfahrungen: https://thenewstack.io/one-year-of-remote-kubernetes-develop...
    • Das könnte mit der Größe zusammenhängen. Unser Unternehmen hat etwa 7.000 Mitarbeitende, und wir haben vor ein paar Jahren einen ähnlichen Weg eingeschlagen. Es hat gedauert, bis remote besser war als lokal, aber inzwischen ist es eindeutig besser.
      Dadurch wurden auch einige Dinge möglich, die in einer rein lokalen Version unmöglich waren. Wenn man etwa zwischen mehreren Branches wechselt, ist die Verzögerung beim Kontextwechsel viel geringer, wenn man statt lokaler Dateien die Maschine wechselt.
    • Stimme vollkommen zu. Wenn man die gesamte Lösung nicht komplett lokal ausführen kann, entsteht enorme Reibung dabei, diese Lösung zu verstehen und über sie nachzudenken.
      Wenn man für irgendetwas mehr als 200 Komponenten hochfahren muss, ist es schwierig, auch nur an einem einzelnen Teil zu arbeiten, der nur mit ein paar davon interagiert.
      In einer Zeit, in der es Server mit 128+ Kernen und 256+ Threads gibt, neige ich immer mehr zu der Ansicht, dass für die meiste Software wieder ein Monolith besser ist.
    • In unserem Unternehmen laufen auf den Cloud-Developer-Boxen so viel gedankenlos installierter Linux-Antivirus und sonstiger Kram, dass Builds selbst auf großen Instanztypen mehr als 10-mal langsamer sind als auf Notebooks und Hunderte Male langsamer als auf echten Entwicklungsmaschinen wie einem Threadripper.
      Reine Geld- und Zeitverschwendung. Wenn man jeden Systemaufruf mit Vendor-Junkware hookt, merkt man, dass das schlecht für Unix-artige Toolchains ist, die Unmengen von Subprozessen starten.
    • Ich denke, das ist eher eine Frage der personellen Ausstattung.
      Bei großen Tech-Unternehmen wie Google und Meta liegt die Entwicklungsumgebung der meisten Software Engineers in der Cloud.
      Das ist eine deutlich bessere Developer Experience als lokal.
  • Für iOS-Entwicklung kam ich bei meiner eigenen Recherche unter Einbeziehung der Kosten zu folgendem Schluss.
    Der M2 Pro ist gut, aber der Fortschritt gegenüber dem 10-Core-M1 Pro ist nicht besonders groß. Im XcodeBenchmark sind es 136 Sekunden gegenüber 120 Sekunden: https://github.com/devMEremenko/XcodeBenchmark
    Der M3 Pro wirkt abgeschwächt, um ihn vom M3 Max abzugrenzen, und mit nur 6 Performance-Kernen ist er im Grunde ähnlich wie der M2 Pro.
    Am Ende habe ich einen leicht gebrauchten 10-Core-M1 Pro gekauft und bin sehr zufrieden. Für weniger als die Hälfte des Preises eines Basis-M3 Pro bekam ich 85 % der Performance; außerdem habe ich berücksichtigt, dass eine CPU im Allgemeinen mindestens 33–50 % schneller sein muss, damit man den Unterschied spürt.

    • Dass der M3 Pro abgeschwächt sei, wurde seit der Vorstellung im Internet ständig wiederholt, aber tatsächlich ist er eine hervorragende Option.
      Er ist deutlich effizienter als der M2 Pro und dabei etwas schneller. Genau das will ich bei einem Notebook, und Speicherbandbreite brauche ich eigentlich nicht.
    • Meine Erfahrung war ähnlich. Bei realen Kompilierzeiten hält der M1 Pro immer noch ziemlich gut mit den aktuellen Notebook-Modellen M2 und M3 mit.
      So groß wie der Unterschied in diesem Artikel war es nicht. Das kann je nach Sprache oder Projekt anders sein, aber als ich denselben Compile-Befehl direkt nebeneinander benchmarkte, sah ich keinen so großen Unterschied.
    • Interessant ist, dass die Verbesserung beim M2 kleiner war als hier gezeigt.
      Bei einer anderen Compiler-Toolchain ist das nicht überraschend, und auch bei der Go-Toolchain sieht man, dass bestimmte Spezifikationen je nach Build-Phase unterschiedlich wirken, etwa dass zusätzlicher Speicher der Linker-Performance hilft.
      Ich habe auch mehrfach Reaktionen gesehen, dass die M3-Performance seltsam begrenzt sei; hoffentlich setzt sich das bei den Modellen ab M4 nicht fort.
    • Ich habe kürzlich dieselbe Rechnung gemacht und am Ende einen M1 Pro mit maximal ausgebautem Arbeitsspeicher und Speicher gekauft. Das war ein guter Deal und ist ein hervorragender Computer.
    • Für iOS-Entwicklung gefällt mir das M1 MacBook Air. Aus der Pro-Linie hätte ich gern nur das Display, besonders die PPI.
      120 Hz wären auch schön, aber ich glaube nicht, dass das in die Air-Notebooks kommt.
  • Ich war früher Core-Contributor bei Chromium und Node.js und bin derzeit Core-Contributor bei gRPC Core/C++; wegen Build-Zeiten habe ich mir nie groß Sorgen gemacht.
    Es gibt „interaktive Builds“, also inkrementelle Builds, um relevante Unit-Tests während der Arbeit erneut auszuführen, und nichtinteraktive Builds, die man startet, während man Kaffee holt oder E-Mails liest. Ich habe noch nie erlebt, dass ein Hardwaretausch aus einem nichtinteraktiven Build einen interaktiven gemacht hätte.
    Meine private Maschine ist ein über fünf Jahre alter Intel i7 mit 16 GB Arbeitsspeicher; als ich merkte, dass ich zum Linken von Node.js unter WSL mehr Speicher brauche, habe ich weitere 16 GB hinzugefügt.
    Mein Arbeitslaptop ist ein Intel MacBook Pro mit Touch Bar, und ich glaube nicht, dass das großen Einfluss auf meine Produktivität hat. Wichtig sind Bildschirmgröße und -qualität sowie die Geschwindigkeit des Speichers. Größeren Einfluss als CPU-Fortschritte hat das Build-System, etwa die Geschwindigkeit inkrementeller Builds und Unterstützung für verteilte Builds. Für persönliche Projekte nutze ich Bazel.

    • Programmierer scheinen sich damit abgefunden zu haben, dass Kompilieren und Linken lange dauern, obwohl sich bei einer winzigen Änderung an einer einzelnen Funktion nur ein paar Bytes im Binary ändern.
      Kompilieren und Linken sollten eigentlich praktisch sofort fertig sein, so schnell, dass man die Kompilierphase gar nicht bemerkt.
      Release-Builds mit Techniken wie Whole-Program Optimization dürfen ruhig lange dauern, aber der normale Compile-/Debug-/Test-Loop kann unmittelbar sein. Das Kompilieren von Systemsprachen ist aus Legacy-Gründen unglaublich langsam, aber das muss nicht so sein.
    • Ich habe auch Blaze genutzt und wollte Bazel für persönliche Projekte ausprobieren, aber bei einem Projekt mit Docker-isiertem Backend und Frontend wurden die Build-Regeln sehr schnell seltsam und speziell.
      Weil ich viel Zeit mit BUILD-Dateien verbrachte, fragte ich mich, ob es gegenüber einem gewöhnlichen Makefile überhaupt einen Mehrwert hat. Das war vor drei Jahren, vielleicht ist das öffentliche Ökosystem inzwischen besser geworden.
    • Ich denke, die M-Serie ist den Intel-MBPs bei Bildschirm und Speichergeschwindigkeit ziemlich überlegen. Als ich beruflich von einem Intel-MBP auf einen M1 gewechselt bin, war der Bildschirm eindeutig viel besser.
      Zur Speichergeschwindigkeit kann ich wenig sagen; unsere Builds laufen alle auf leistungsstarken Remote-Entwicklungsmaschinen.
    • Das liegt daran, dass du auf Bazel konditioniert bist. Ging mir auch so.
    • Chromium ist ein riesiges Projekt. Bei Projekten von etwas üblicherer Größe kann man auf einem Laptop vollständige Builds in vernünftiger Zeit schaffen.
  • Für Leute, die wie im Artikel Datenanalyse mit KI machen wollen, halte ich es für viel einfacher, die Daten in R, Stata o. Ä. zu laden und direkt abzufragen.
    Die Befehle sind kürzer und präziser und vor allem ist die Reproduzierbarkeit höher.
    Das Schwierigste bei der Datenanalyse ist, die Daten und den Mechanismus zu verstehen, der sie erzeugt hat. Dafür braucht man ein kausales Modell der Problemdomäne.
    Wenn die KI nicht zuvor mit anderen Daten aus diesem Bereich trainiert wurde, weiß ich nicht, ob sie ein nützliches kausales Modell erstellen kann. Ohne dieses Modell ist es unmöglich, Daten sinnvoll zu interpretieren, und ich frage mich auch, ob aktuelle KI-Modelle Confounding, übermäßigen Einfluss von Ausreißern und interessante Effektmoderatoren erkennen können.

    • Ein KI-Assistent auf Basis von GPT-4 macht im Grunde genau das.
      Bei mir waren es Python und pandas, und man kann ihn bitten, den für die Analyse verwendeten Code zu zeigen.
      Der Unterschied ist, ob man die Daten in R/Python lädt und nach „Wie mache ich xyzzzy?“ sucht und den Code selbst schreibt, oder ob man ChatGPT nutzt.
  • Der Teil „Alle Entwickler führen die vollständige incident.io-Umgebung lokal auf ihrem Laptop aus und bekommen einen Feedback-Loop von unter 30 Sekunden von Codeänderung bis Ausführung“ wirkt auf mich wie der größte Erfolg.
    Abgesehen von ein paar Fällen, in denen ich Startups kurz geholfen habe, gab es kein Unternehmen, bei dem ich die gesamte Entwicklungs-/lokale Instanz der Firma auf einer Maschine ausführen konnte.
    Es gab immer irgendetwas, auf das man keinen Zugriff hatte, und immer irgendwelche Fallen.

    • Bis zu meiner jüngsten Stelle konnte ich diese verdammte App nicht lokal ausführen, und das hat mich wirklich wahnsinnig gemacht.
      Ich verstehe nicht, warum sich Leute über eine so schreckliche Developer Experience nicht mehr aufregen. Die heutigen Uni-Absolventen scheinen gar nicht zu wissen, was ihnen entgeht.
    • Ich habe einmal bei so einem Unternehmen gearbeitet, und nachdem ich weg war, habe ich das wirklich sehr vermisst.
      Wer diese Welt nicht erlebt hat, versteht nicht, wie viel besser sie ist, und rationalisiert es auf alle möglichen Arten.
    • Es ist schwer vorstellbar, dass man das nicht hat. Wir lassen mit k3s alles lokal laufen, und das funktioniert gut.
      Allerdings haben wir letztes Jahr Snowflake hinzugefügt; es löst zwar echte Probleme, aber iterative Entwicklung an diesem Teil ist schmerzhaft.
    • Früher war das möglich, aber mit wachsender Größe wird es schwer zu unterstützen. Der Aufwand wächst in Bezug auf die Unternehmensgröße ungefähr quadratisch.
      Er ist linear zur Anzahl der zu unterstützenden Services und linear zur Anzahl der zu unterstützenden Engineers. Außerdem entstehen verschiedenste Use Cases, die nicht gut zusammenpassen, irgendwann wird das Infrastrukturteam zum Flaschenhals für Feature-Releases, und die Leute beginnen, jeweils eigene Wege zu gehen.
      Wenn diese Büchse der Pandora einmal offen ist, lässt sich das praktisch nicht mehr zurückdrehen. Trotzdem ist es viel wichtiger, Entwicklungszyklen von Stunden oder Tagen auf Minuten zu verkürzen, als ein paar Minuten um 25 % zu reduzieren.
    • Bei der App, die ich gerade baue, gebe ich mein Bestes, um das zu ermöglichen. Da wir ein Objekterkennungsmodell und Stable Diffusion ausführen müssen, musste ich den CEO überzeugen, dass ein M2 Max helfen würde.
      Bisher läuft es gut.
  • Als Autor: Danke fürs Teilen.
    Es steckt einiges drin, etwa Profiling der Go-Kompilierung, der Bau eines Hot Reloaders und die Analyse des Build-Datensatzes mit KI.
    Unterm Strich hat sich das Upgrade vom M1 auf den M3 Pro gelohnt, und in den Tests machte der Max keinen großen Unterschied. Der M2 liegt ziemlich nah am M3, daher lohnte sich ein Upgrade für uns nicht.
    Wenn es Fragen gibt, kann ich sie beantworten.

    • Danke für die ausführliche Analyse; mich würde interessieren, ob du die Kosten der Engineering-Zeit für diese Analyse berechnet hast.
      Mich würde auch interessieren, wie sich diese Kosten auf die Amortisationszeit auswirken.
    • Mich würde interessieren, wie ihr zu dem Schluss gekommen seid, dass die Max-SKU nicht wesentlich schneller ist. Die Verteilung im Chart sieht schneller aus, aber im Text darunter heißt es nur, sie wirke ähnlich.
    • Kann man davon ausgehen, dass der M3 Max nur geringe Vorteile hatte, weil die Workload die Cores nicht richtig ausnutzen konnte?
      Oder könnte es auch sein, dass die Jobs so schnell fertig waren, dass es in der tatsächlichen Nutzung keinen Unterschied machte?
    • Mich würde interessieren, ob der Manager einige Deliverables verschoben hat, um Zeit für diese Arbeit zu schaffen, oder ob sie eher nebenbei lief.
    • Das war ein interessanter Vergleich. Falls möglich, würde ich zusätzlich gerne Builds auf einer Maschine mit 8 GB Arbeitsspeicher sehen.
  • Die Idee ist interessant, aber die Qualität der Datenanalyse wirkt ziemlich schwach, und ich bin nicht sicher, ob man daraus wirklich das lernt, was man zu lernen glaubt.
    Besonders schwer nachzuvollziehen ist, warum der Anteil der Builds unter 20 Sekunden beim Wechsel vom M1 Pro zum M2 Pro so dramatisch steigt. Bei Code-Compile-Workloads liegt der reale Leistungsunterschied zwischen beiden ungefähr bei 20–25 %.
    Es ergibt auch nicht recht Sinn, dass M3-Maschinen weniger Builds unter 20 Sekunden haben als M2-Maschinen oder dass ein M3 Pro mit halb so vielen Kernen mehr Builds unter 20 Sekunden hat als ein M3 Max.
    Wahrscheinlicher ist, dass Unterschiede im Verhalten der Entwickler solche Abweichungen erzeugen, etwa weil Leute mit unterschiedlichen Notebook-Typen typischerweise an unterschiedlichen Aufgaben arbeiten.
    Ein paar Eindrücke nach grobem Lesen: Der Go-Compiler scheint zusätzliche Kerne kaum auszunutzen, die Art, wie die Daten zusammengeführt werden, ist grundsätzlich unhandlich, und auch die Vergleichsmethode ist inkonsistent, weil Histogramme und gebinnte Dichteplots gemischt werden und die y-Achsenbereiche variieren.
    Macs drosseln die CPU-Leistung nicht nur deshalb, weil sie im Akkubetrieb laufen. Falls Builds im Akkubetrieb wirklich langsamer sind, lässt sich das allein aus den Diagrammen schwer sicher sagen, aber vermutlich liegt es daran, dass die Einstellung „Energiesparmodus“ aktiviert war.

    • Der M3 hat eine geringere Speicherbandbreite und ist in manchen Anwendungsfällen faktisch ein Downgrade.
  • Etwas off-topic, aber ich frage mich, wie andere Unternehmen Endpoint-Management und Sicherheitssoftware mit Entwicklerproduktivität in Einklang bringen.
    Bei uns laufen auf Entwickler-Notebooks, sowohl unter macOS als auch unter Windows, mehr als fünf Hintergrunddienste. Dazu gehören Endpoint-Management, Abfangen von Rechteerhöhungen, TLS-Interception und -Prüfung, Malware-Schutz und ein VPN-Client.
    Diese Kombination hat deutliche Auswirkungen auf die Performance. Egal, was man auf der Maschine tut: Diese Dienste fressen CPU- und I/O-Leistung, und Entwickler klagen seit Längerem über zufällige Hänger und Ruckler.
    Angesichts der Zunahme von Ransomware und Diebstahl geistigen Eigentums verstehe ich, dass Sicherheit notwendig ist, aber ich frage mich, ob es Unternehmen gibt, die bessere Wege gefunden haben, Sicherheit mit weniger Einfluss auf die Entwicklerproduktivität bereitzustellen.

    • Der einzige Ansatz, den ich gesehen habe, war, IT/Support zu informieren, wenn es schlimmer wurde, und ihnen Ordner und Dateien zu nennen, die ausgeschlossen werden sollten, damit Dinge wie temporäre Build-Dateien nicht durch Scans ausgebremst werden.