1 Punkte von GN⁺ 6 시간 전 | 1 Kommentare | Auf WhatsApp teilen
  • Performance-Optimierung ist ein wirkungsvolles Mittel, um komplexe Systeme zu verstehen und Produkte zu verbessern, aber selbst 10-mal schnellere Ergebnisse verändern die tatsächliche Arbeitsweise oder den Durchsatz möglicherweise nicht
  • Selbst wenn sich die Antwortzeit von Abfragen von 5–10 Minuten auf 30 Sekunden bis 1 Minute verkürzt, ist der wahrgenommene Effekt begrenzt, sobald die Schwelle von etwa 10 Sekunden überschritten wird, ab der Menschen ihre Aufmerksamkeit nicht mehr aufrechterhalten
  • Wenn Arbeit in ganzzahligen Einheiten wie ein oder zwei Vorgängen pro Tag gebündelt ist, reichen Verbesserungen von 25–50 % nicht aus; erst wenn jeder Vorgang einschließlich Fahrzeit unter 4 Stunden liegt, sind 2 Vorgänge pro Tag möglich
  • In Datenpipelines erzeugen langsame Stufen Backpressure nach oben, sodass eine einzelne stark beschleunigte Stufe den End-to-End-Durchsatz nicht erhöht, solange nicht alle Engpässe beseitigt sind
  • Leistungsverbesserungen sollten nicht anhand einzelner Benchmarks, sondern anhand des gewünschten Ergebnisses bewertet werden; wenn Grenzen wie Aufmerksamkeitsspanne, Zunahme der Arbeitseinheiten oder Gesamtdurchsatz nicht überschritten werden, bleibt selbst eine große Verbesserung in der Praxis wirkungsarm

Warum Performance-Zahlen und reale Ergebnisse auseinanderlaufen

  • Arbeit an der Performance ist lohnend, weil sie Systeme effizienter macht und Kunden neue Möglichkeiten eröffnen kann
  • Sie hilft auch dabei, empirisch zu verstehen, wie komplexe Systeme unter Größe und Last zusammenwirken
  • Bei der engen Arbeit am System entstehen Ideen zur Verbesserung von Produkten und Services, von denen manche nicht direkt mit Performance-Optimierung zu tun haben
  • Allerdings können gut aussehende Ergebnisse wie „10-mal schneller“ oder „50 % weniger Ressourcen“ die erwartete Veränderung verfehlen, wenn verborgene Einschränkungen nicht überwunden werden

Jenseits von 10 Sekunden bricht die Aufmerksamkeit der Nutzer ab

  • In einem Fall wurde die Abfrage-Performance einer neuen Datenbank verbessert: Die teuersten Abfragen in der bisherigen Datenbank, die 5–10 Minuten dauerten, wurden auf 30 Sekunden bis 1 Minute reduziert
  • Das war zwar eine Verbesserung um etwa den Faktor 10, doch um die Nutzererfahrung tatsächlich zu verändern, war noch einmal ein großer Sprung nötig
  • Forschung zur Mensch-Computer-Interaktion betrachtet ungefähr 10 Sekunden als Grenze dafür, wie lange Menschen ihre Aufmerksamkeit für eine Gesamtaufgabe aufrechterhalten können
    • 0,1 Sekunden ist die Schwelle, bei der Feedback als unmittelbar wahrgenommen wird
    • Etwa 1 Sekunde ist die Schwelle, bei der der Arbeitsfluss erhalten bleibt
    • Etwa 10 Sekunden ist die Schwelle, bis zu der die Aufmerksamkeit für die Gesamtaufgabe erhalten bleibt
    • Feedback wie Fortschrittsanzeigen oder geschätzte Dauer kann helfen, die Aufmerksamkeit aufrechtzuerhalten
  • Sowohl 30 Sekunden als auch 5 Minuten liegen über 10 Sekunden, daher schauen Nutzer auf Nachrichten, holen sich einen Kaffee, beginnen ein Gespräch oder wechseln zu einer anderen Aufgabe
  • Wenn Nutzer einige Minuten oder Stunden später zurückkehren und die UI bereits geladen ist, macht es für die Arbeitsweise oft keinen großen Unterschied, ob die tatsächliche Wartezeit 30 Sekunden oder 5 Minuten betrug
  • In diesem Projekt gelang es schließlich, viele Abfragen auf unter 10 Sekunden zu bringen, und einige Abfragen, die zuvor wegen Timeouts unmöglich waren, wurden überhaupt erst möglich
    • Nicht nur die Latenz der Datenabfragen, sondern auch die Latenz von Metadatenabfragen und die Renderzeit der Webseiten waren wichtig für die Gesamtverbesserung
    • Durch asynchrones IO und verbesserte Datenaggregation besteht Potenzial für einen weiteren 10-fachen Sprung; dann könnten Abfragen, die früher mehrere Minuten dauerten, in unter 1 Sekunde zurückkommen

Die Schwelle vom einen zum zweiten Vorgang pro Tag

  • In einem Projekt wurde der Gesamtprozess durch Automatisierung manueller Arbeit, das Entfernen unnötiger Schritte, teilweise Parallelisierung und das Aufschieben von Schritten, die später asynchron verarbeitet werden konnten, von mehreren Stunden auf stabil unter 1 Stunde reduziert
  • Die Verbesserung lag grob bei 25–50 %, doch der Gesamtprozess änderte sich wegen logistischer Einschränkungen nicht
  • Man kann an Installateure, Elektriker oder Tischler denken, die einen Ort einplanen, dorthin fahren und dann die Arbeit abschließen müssen
    • Wenn pro Tag 8 Stunden gearbeitet wird und ein Einsatz an einem Ort 8 Stunden dauert, reichen auch 2–3 eingesparte Stunden nicht, um noch zu einem neuen Ort zu fahren und dort eine neue Arbeit abzuschließen
    • Erst wenn jeder Einsatz einschließlich Fahrzeit 4 Stunden oder weniger dauert, lassen sich 2 Einsätze pro Tag abschließen
  • Bevor diese Schwelle überschritten wird, führen Effizienzverbesserungen in Zwischenschritten nicht zu einer höheren Produktionsmenge
  • Der Fokus auf Performance kann zugleich Qualitäts- und Zuverlässigkeitsverbesserungen ermöglichen, die die Kundenerfahrung direkt beeinflussen
    • Selbst kleine Performance-Verbesserungen, die in Produktion keinen Durchbruch bringen, können Testumgebungen beschleunigen und damit Feature-Entwicklung und Fehlerbehebung schneller machen

Engpässe in Pipelines mit Backpressure

  • Viele Infrastrukturen für Business-Software enthalten Datenpipelines, die Ereignisse aus vielen Quellen wie Fahrzeugen, Fabrikanlagen, Mobiltelefonen oder Finanztransaktionen verarbeiten
  • Ereignisse werden üblicherweise in einem langlebigen Log gespeichert, das von nachgelagerten Services konsumiert und verarbeitet wird
  • Für hohen Durchsatz im großen Maßstab muss das Log partitioniert werden, und nachgelagerte Services nutzen Techniken wie Batching, Pipelining, Parallelität, effiziente Speicherallokation und dynamische Skalierung
  • Engpässe in Datenpipelines sind schwer zu finden, weil das Systemverhalten miteinander verknüpft ist
    • Langsame Stufen erzeugen absichtlich Backpressure auf vorgelagerte Stufen
    • Wenn es mehrere Engpässe gibt, steigt der Gesamtdurchsatz erst, wenn auch der letzte Engpass beseitigt ist
  • Die Pipeline in Stufen zu zerlegen und die Performance-Eigenschaften und Grenzen jeder Stufe zu verstehen, ist gute Engineering-Praxis
  • Dennoch kann selbst eine Verbesserung einer einzelnen Stufe um mehrere Größenordnungen ohne Einfluss auf den Gesamtdurchsatz bleiben
  • Bei Durchsatzverbesserungen ist nicht der Benchmark einzelner Stufen entscheidend, sondern der End-to-End-Durchsatz

Ein empirischer Ansatz zum Finden von Engpässen

  • Um die Dynamik und Engpässe solcher Systeme zu verstehen, ist es nützlich, sie empirisch vom Anfang der Pipeline an zu untersuchen
  • Zum Beispiel beginnt man mit einer Stufe, die Ereignisse aus einem verteilten Log liest und verwirft
    • Wenn schon diese Stufe den Zieldurchsatz nicht erreicht, ist die Optimierung nachgelagerter Stufen Zeitverschwendung
  • Benchmarks nachgelagerter Komponenten, etwa wie viele Zeilen pro Sekunde in eine Datenbank eingefügt werden können, können ebenfalls wichtig sein, aber die Analyse sollte stromaufwärts beginnen
  • Auch Simulationen sind eine wertvolle Methode, um komplexe Systeme und Performance zu verstehen

Der Maßstab für Performance-Verbesserungen ist das gewünschte Ergebnis

  • Arbeit an der Performance ist schwierig, aber auch ein Training darin, komplexe Systeme tief zu verstehen und bessere Produkte zu bauen
  • Wenn die Aufmerksamkeit von Menschen gehalten werden soll, muss die Antwort innerhalb von ungefähr 10 Sekunden erfolgen
  • Wenn ganze Arbeitseinheiten die Einschränkung sind, reichen prozentuale Verbesserungen nicht aus; es muss möglich werden, von einem auf zwei Vorgänge pro Tag zu kommen
  • Um den Durchsatz einer Pipeline mit Backpressure zu maximieren, reicht es oft nicht, ein oder zwei Engpässe zu beheben; häufig müssen alle Engpässe gelöst werden
  • Werden diese Grenzen nicht überschritten, kann selbst eine Performance-Verbesserung um den Faktor 10 das gewünschte Ergebnis verfehlen

1 Kommentare

 
GN⁺ 6 시간 전
Kommentare auf Lobste.rs
  • Wenn man einen einzelnen Schritt um ein Vielfaches verbessert und dann enttäuscht ist, weil das keinen Einfluss auf den Gesamtdurchsatz hat, lohnt hier ein Blick auf Amdahls Gesetz

    • Ich frage mich, ob es so etwas wie eine Sammlung von Namen für Gesetze aus der Informatik insgesamt gibt.
      Ich höre ständig von neuen Gesetzen, aber sie sind oft so nischig, dass sie nicht häufig verwendet werden und ich sie wieder vergesse. Das heißt aber nicht, dass solche Gesetze als Wissen einer Generation nicht gültig oder nützlich wären.
  • Ich frage mich, warum man überhaupt einen Teil optimiert hat, der nur einen winzigen Bruchteil der Gesamtzeit ausmacht.
    Ob es an schlechter Anleitung lag oder an fehlenden Performance-Tools, weiß ich nicht. Nur wenige wollen bewusst an Dingen arbeiten, die fast keine Wirkung haben; meist steckt ein größeres Problem dahinter.

    • Ein möglicher Weg, wie so etwas passiert, sieht meiner Meinung nach ungefähr so aus:
      Man schaut sich ein Problem an, in den Sampling-Ergebnissen fällt eine bestimmte Funktion stark auf, und nach kurzem Hinsehen scheint die Implementierung recht leicht verbesserbar zu sein. Aber man ist gerade mit etwas anderem beschäftigt und verschiebt es auf „später“.
      Später erinnert man sich an diese einfache Verbesserung und fängt an, doch die Änderung wird komplizierter als gedacht; trotzdem entsteht Tunnelblick, man will das Rätsel lösen und verbringt viel Zeit damit.
      In Wirklichkeit war das Performance-Problem nur nebensächlich. Im damaligen Kontext sah es anteilig groß aus, die absolute Zeit war kaum relevant, oder die Situation war nicht CPU-, sondern I/O-limitiert. Es ist eine Art Nerd Sniping, das man sich selbst antut.
    • Bei Google gab es einmal einen Vorschlag, einen Teil einer Pipeline zu optimieren, und mehrere Leute erklärten, dass dieser Teil weniger als 0,1 % der gesamten Rechenarbeit ausmachte und der Gesamtgewinn definitionsgemäß ebenfalls unter 0,1 % liegen würde.
      Das wurde trotzdem ignoriert und die Optimierung umgesetzt; als die Gesamtverbesserung dann unter 0,1 % lag, war man verwirrt. Mit Domänenwissen war auch intuitiv klar, dass dieser Teil nicht teuer war, aber um Zeitverschwendung zu vermeiden, halfen wir sogar dabei, die tatsächlichen Performance-Kosten zu messen.
    • Möglicherweise handelte man auf Basis von Vermutungen, hatte immer angewandte Best Practices verinnerlicht oder verallgemeinerte reale Probleme aus einem begrenzten Kontext zu stark.
      Oder der Benchmark war irreführend. Nicht jedes System zeigt in der Produktionsumgebung die Kosten jeder Methode oder jedes Prozesses einfach an.
      Diese Erklärungen sind in unterschiedlichem Maße allesamt eher dysfunktional; manche liegen eher bei der Person, andere eher in der Umgebung.
    • Es gibt einige mögliche Gründe:
      1. Ein talentierter Junior Engineer hat gelernt, Probleme zu lösen, aber nicht, Probleme auszuwählen, deren Lösung sich lohnt. Jede gefundene Ineffizienz wird angegriffen, unabhängig vom End-to-End-Effekt. Mit Glück bringt es jemand bei; andernfalls stagniert die Person als Senior Engineer, den der PM stark kontrollieren muss.
      2. Die End-to-End-Performance ist nicht richtig sichtbar. Irgendwo im System gibt es eine Performance-Verschlechterung, das Management macht Druck, aber man bekommt keine Befugnis, ordentliches Monitoring einzuführen; also fasst man auf Verdacht mehrere Komponenten an und hofft, dass eine davon die richtige ist. Sobald das akute Problem vorbei ist, kehrt man wieder zum Ausliefern von Nutzer-Features zurück.
      3. Es ist jetzt noch kein Problem, aber man behebt es im Voraus, weil es bald eines werden könnte. Wenn man genug Einfluss hat oder Überstunden durchdrücken kann, macht man es, auch wenn es aktuell keinen sichtbaren Effekt gibt. Auch hervorragende Engineers setzen politisches Kapital für so etwas ein, wenn sie glauben, dass es künftig wichtig wird; weniger gute Engineers verbrennen dabei alles.
        3.1. Wenn man bei einem Hyperscaler arbeitet, kann schon eine Einsparung von 0,1 % Rechenaufwand, die für Nutzer völlig unsichtbar ist, die Gewinn-und-Verlust-Rechnung um den Preis eines Strandhauses beeinflussen.
      4. Man kann einer Herausforderung nicht widerstehen. Man weiß eigentlich, dass sich dadurch nichts ändert, aber nach lauter CRUD-Apps ist einem langweilig geworden, und nun bietet sich die Gelegenheit, etwas auszuprobieren, das man in einem Blog gesehen hat. Man nerd-sniped sich selbst, um die Last der Sinnlosigkeit zu mindern.
    • Entgegen der landläufigen Meinung bestehen viele Systeme nicht nur aus ein paar Bottlenecks.
      Häufig sind die üblichen Programmierpraktiken selbst insgesamt langsam. Man denke etwa an objektorientierten Code mit vielen Zeigern und massenhaft Heap-Allokationen über einen allgemeinen Allocator. Egal, wo man ansetzt, es ist nur ein kleiner Teil der Gesamtzeit; im schlimmsten Fall hilft außer einer kompletten Neuschreibung nichts. Mit Glück kann man schrittweise neu schreiben.
      Selbst wenn es nur zwei Bottlenecks gibt und sie innerhalb eines einstelligen Faktors voneinander liegen, bringt selbst die perfekte Behebung des schlimmsten Bottlenecks nicht einmal eine einstellige Beschleunigung. In vielen Fällen muss man, wie im Artikel beschrieben, deutlich mehr überwinden, um einen relevanten Gewinn zu erzielen.
      Außerdem ähneln Computer eher parallel laufenden verteilten Systemen. Es gibt mehrere CPUs, GPUs, Disks, Ethernet usw., und die Geschwindigkeit eines Prozesses wird durch die langsamste Stufe der Pipeline begrenzt. Behebt man diese Stufe, begrenzt die nächstlangsamere; im schlimmsten Fall gibt es mehrere langsamste Stufen, sodass die Behebung nur einer davon gar keinen Gewinn bringt.
      Das ist aber noch die wohlwollende Erklärung; manchmal verfällt man einfach dem Optimierungsspiel, verliert die Prioritäten aus den Augen oder macht Fehler.
  • Auch wenn Nutzer es nicht bemerken, ist eine Reduzierung der Rechenzeit von Software weiterhin gut.
    Denn sie kann Kosten senken und Skalierung erleichtern.

    • Das hängt von den Komplexitätskosten ab.
      Wenn man Code um den Preis übermäßiger Komplexität schneller macht, entstehen – von der Wartbarkeit ganz abgesehen – langfristig Folgewirkungen, die der Performance schaden. Bei Strukturänderungen bleibt Code zurück, der inzwischen unnötig geworden ist; um ihn zu verstehen oder zu entfernen, muss man die gesamte Komplexität vollständig begreifen.
      „Es wird schneller“ sollte kein Freibrief sein, Bedenken hinsichtlich Komplexität oder Wartbarkeit zu ignorieren.
  • Ich bin gerade in einer ähnlichen Situation und reduziere mit mehreren kleinen Projekten eine Abfrage, die 5 Minuten dauerte, auf unter 30 Sekunden.
    Ich sage dem Team, dass das langfristig nicht ausreicht, aber es ist eindeutig eine Verbesserung und hat großen Einfluss.
    Aus Kundensicht sinkt die Wartezeit von wutmachend auf nur noch nervig.
    Der Fokus liegt aktuell nicht auf der Performance pro Nutzer, sondern auf der Gesamtperformance. Wenn man Dutzende Prozesse von 5, 10 oder 30 Minuten optimiert, verringert sich die Konkurrenz um Ressourcen mit anderen Teilen des Systems deutlich. 10 Minuten lang auf die Datenbank einzuhämmern ist sehr lang, und am Ende wird alles schneller, wovon alle profitieren.