it-swarm.com.de

Wann ist es besser, eine Software zu Beginn oder am Ende der Entwicklung für eine bessere Leistung zu optimieren?

Ich bin ein Junior-Softwareentwickler und habe mich gefragt, wann der beste Zeitpunkt ist, um eine Software für eine bessere Leistung (Geschwindigkeit) zu optimieren.

Angenommen, die Software ist nicht extrem groß und komplex in der Verwaltung. Ist es besser, zu Beginn mehr Zeit für die Optimierung aufzuwenden, oder sollte ich einfach die Software entwickeln, die alle Funktionen korrekt ausführt, und sie dann für eine bessere Leistung optimieren?

19
joepr

Die Nummer eins sollte immer und für immer die Lesbarkeit sein. Wenn es langsam, aber lesbar ist, kann ich es beheben. Wenn es kaputt, aber lesbar ist, kann ich es beheben. Wenn es nicht lesbar ist, muss ich jemand anderen fragen, was das überhaupt tun sollte.

Es ist bemerkenswert, wie leistungsfähig Ihr Code sein kann, wenn Sie sich nur darauf konzentriert haben, lesbar zu sein. So sehr, dass ich die Leistung im Allgemeinen ignoriere, bis ich einen Grund zur Sorge habe. Das sollte nicht so verstanden werden, dass mir die Geschwindigkeit egal ist. Ich mache. Ich habe gerade festgestellt, dass es nur sehr wenige Probleme gibt, deren Lösungen tatsächlich schneller sind, wenn sie schwer lesbar sind.

Nur zwei Dinge bringen mich aus diesem Modus heraus:

  1. Wenn ich eine Chance auf eine ausgewachsene großes O Verbesserung sehe, auch dann nur, wenn n groß genug ist, dass es jeden interessieren würde .
  2. Wenn ich Tests habe, die echte Leistungsprobleme zeigen. Selbst mit jahrzehntelanger Erfahrung vertraue ich den Tests immer noch mehr als meiner Mathematik. Und ich bin gut in Mathe.

Vermeiden Sie auf jeden Fall Analyse-Lähmung , indem Sie sich denken lassen, Sie sollten keine Lösung ausprobieren, da diese möglicherweise nicht die schnellste ist. Ihr Code profitiert tatsächlich, wenn Sie mehrere Lösungen ausprobieren, da Sie durch die Änderungen ein Design verwenden müssen, das das Ändern erleichtert. Eine flexible Codebasis kann später dort schneller erstellt werden, wo sie wirklich benötigt wird. Wählen Sie flexibel über Geschwindigkeit und Sie können die Geschwindigkeit wählen, die Sie benötigen.

54
candied_orange

Wenn ein bestimmtes Leistungsniveau erforderlich ist (eine nicht funktionale Anforderung), sollte dies von Anfang an ein Entwurfsziel sein. Z.B. Dies kann Einfluss darauf haben, welche Technologien geeignet sind oder wie Sie den Datenfluss im Programm strukturieren.

Im Allgemeinen ist es jedoch nicht möglich, vor dem Schreiben des Codes zu optimieren: erst funktionieren, dann richtig machen und schließlich schnell machen .

Ein großes Problem bei der Optimierung vor der Implementierung der meisten Funktionen besteht darin, dass Sie sich an den falschen Stellen auf suboptimale Entwurfsentscheidungen festgelegt haben. Es gibt oft (aber nicht unbedingt) einen Kompromiss zwischen Wartbarkeit und Leistung. Die meisten Teile Ihres Programms sind für die Leistung völlig irrelevant! Typische Programme haben nur wenige Hotspots, die es wirklich wert sind, optimiert zu werden. Es ist also ein wirklich schlechter Handel, die Wartbarkeit für die Leistung an all jenen Orten zu opfern, die keine Leistung benötigen.

Die Optimierung auf Wartbarkeit ist der bessere Ansatz. Wenn Sie Ihre Klugheit für Wartbarkeit und klare Designs ausgeben, fällt es Ihnen auf lange Sicht leichter, kritische Abschnitte zu identifizieren und sicher zu optimieren, ohne das Gesamtdesign zu beeinträchtigen.

27
amon

wann wäre der beste Zeitpunkt, um eine Software für eine bessere Leistung (Geschwindigkeit) zu optimieren?.

Entfernen Sie zunächst das Konzept, dass Leistung dasselbe ist wie Geschwindigkeit. Leistung ist das, was der Benutzer für Leistung hält.

Wenn Sie eine Anwendung doppelt so schnell auf einen Mausklick reagieren lassen und von zehn Mikrosekunden auf fünf Mikrosekunden wechseln, ist es dem Benutzer egal. Wenn Sie eine Anwendung doppelt so schnell auf einen Mausklick reagieren lassen und von viertausend Jahren auf zweitausend Jahre wechseln, ist es dem Benutzer wiederum egal.

Wenn Sie Ihre Anwendung doppelt so schnell erstellen und den gesamten Speicher auf dem Computer verbrauchen und abstürzen, ist es dem Benutzer egal, dass sie jetzt doppelt so schnell ist.

Leistung ist die Wissenschaft, effektive Kompromisse beim Ressourcenverbrauch einzugehen, um eine bestimmte Benutzererfahrung zu erzielen. Die Zeit des Benutzers ist eine wichtige Ressource, aber es geht nie nur um "schneller". Das Erreichen von Leistungszielen erfordert fast immer Kompromisse, und sie tauschen häufig Zeit gegen Raum aus oder umgekehrt.

Angenommen, die Software ist nicht extrem groß und komplex zu verwalten

Das ist eine schreckliche Annahme.

Wenn die Software nicht groß und komplex zu verwalten ist, löst sie wahrscheinlich kein interessantes Problem, das einen Benutzer interessiert, und es ist wahrscheinlich sehr einfach zu optimieren.

ist es besser, zu Beginn mehr Zeit mit der Optimierung zu verbringen, oder sollte ich einfach die Software entwickeln, die alle Funktionen korrekt ausführt, und sie dann für eine bessere Leistung optimieren?

Sie sitzen dort auf einer leeren Seite und schreiben void main() {} Beginnen Sie mit der Optimierung? Es gibt nichts zu optimieren! Die richtige Reihenfolge ist:

  • Lass es kompilieren
  • Mach es richtig
  • Mach es elegant
  • Mach schnell

Wenn Sie versuchen, dies in einer anderen Reihenfolge zu tun, erhalten Sie einen falschen Code, der ein Chaos darstellt, und jetzt haben Sie ein Programm, das sehr schnell falsche Antworten liefert und Änderungen widersteht.

Aber da fehlt ein Schritt. Die echte richtige Reihenfolge ist:

  • Arbeiten Sie mit Kunden und Management zusammen, um realistische, messbare Leistungsmetriken und -ziele festzulegen. Denken Sie daran, dass Geschwindigkeit nicht die einzige Metrik ist, die Kunden interessiert.
  • Implementieren Sie ein Testkabel, mit dem Sie den aktuellen Status des Projekts anhand Ihrer Ziele verfolgen können
  • Lass es kompilieren
  • Führen Sie die Tests aus. Wenn Sie Ihr Ziel nicht mehr erreichen, stellen Sie fest, dass Sie möglicherweise frühzeitig einen schlechten Weg eingeschlagen haben. Verwenden Sie Wissenschaft. Haben Sie einen schlechten Algorithmus eingeführt, der behoben werden kann, oder stimmt etwas grundlegend nicht? Wenn es grundlegend falsch ist, dann fangen Sie von vorne an. Wenn es behoben werden kann, geben Sie einen Fehler ein und kommen Sie später darauf zurück.
  • Mach es richtig
  • Führen Sie die Tests erneut aus ...
  • Mach es elegant
  • Führen Sie die Tests erneut aus ...
  • Sind Sie mit Ihrem Ziel einverstanden? Wenn ja, gehe zum Strand . Wenn nicht, machen Sie es schnell genug .
16
Eric Lippert

In der Regel ist es am besten, die Leistung später zu optimieren. Ich habe jedoch festgestellt, dass viele Projekte schlecht laufen, wenn Entwickler feststellen, dass sie Software erhalten, die zu langsam ist, wenn eine signifikante Last oder Daten hinzugefügt werden.

Ein Mittelweg wäre meiner Meinung nach am besten. Legen Sie nicht zu viel Wert darauf, aber ignorieren Sie die Leistung nicht ganz.

Ich werde ein Beispiel geben, das ich oft gesehen habe; Bei einer ORM-Bibliothek haben wir eine Benutzerentität, die einen oder mehrere Aufträge haben kann. Lassen Sie uns alle Bestellungen für einen Benutzer durchlaufen und herausfinden, wie viel der Benutzer in unserem Geschäft ausgegeben hat - ein naiver Ansatz:

User user = getUser();
int totalAmount;
for (Order o : user.getOrders()) {
  totalAmount += o.getTotalAmount();
} 

Ich habe gesehen, wie Entwickler ähnliche Dinge geschrieben haben, ohne an die Auswirkungen zu denken. Zuerst erhalten wir den Benutzer, der hoffentlich nur eine SQL-Abfrage in der Benutzertabelle ist (aber möglicherweise viel, viel mehr umfasst), dann durchlaufen wir die Bestellungen, einschließlich des Abrufs aller relevanten Daten für alle Bestellpositionen in der Bestellung , Produktinformationen usw. - all dies, um für jede Bestellung eine einzige Ganzzahl zu erhalten!

Die Anzahl der SQL-Abfragen hier könnte Sie überraschen. Dies hängt natürlich davon ab, wie Ihre Entitäten strukturiert sind.

Hier wäre der richtige Ansatz höchstwahrscheinlich, eine separate Funktion hinzuzufügen, um die Summe aus der Datenbank über eine separate Abfrage abzurufen, die in der vom ORM bereitgestellten Abfragesprache geschrieben ist, und ich würde dies befürworten beim ersten Mal und dies nicht für später verschieben; Wenn Sie dies tun, werden Sie wahrscheinlich viel mehr Probleme haben und sich nicht sicher sein, wo Sie anfangen sollen.

3
Vetle

Die Gesamtsystemleistung ist ein Produkt der komplexen Wechselwirkungen der Gesamtheit der Systemkomponenten. Es ist ein nichtlineares System. Daher wird die Leistung nicht nur durch die individuelle Leistung der Komponenten bestimmt, sondern auch durch Engpässe zwischen ihnen.

Natürlich können Sie nicht auf Engpässe testen, wenn noch nicht alle Komponenten Ihres Systems erstellt wurden. Daher können Sie frühzeitig nicht wirklich gut testen. Auf der anderen Seite fällt es Ihnen nach dem Aufbau des Systems möglicherweise nicht so einfach, die Änderungen vorzunehmen, die Sie vornehmen müssen, um die gewünschte Leistung zu erzielen. Das ist also ein Knochen-Fide Catch-22 .

Um die Sache zu erschweren, kann sich Ihr Leistungsprofil drastisch ändern, wenn Sie zu einer produktionsähnlichen Umgebung wechseln, die häufig nicht frühzeitig verfügbar ist.

Also, was machst du? Nun, ein paar Dinge.

  1. Sei pragmatisch. Frühzeitig können Sie Plattformfunktionen verwenden, die für die Leistung "Best Practice" sind. Verwenden Sie beispielsweise Verbindungspooling, asynchrone Transaktionen und vermeiden Sie Statefulness. Dies kann zum Tod einer Multithread-Anwendung führen, bei der verschiedene Mitarbeiter um den Zugriff auf gemeinsam genutzte Daten kämpfen. Normalerweise würden Sie diese Muster nicht auf Leistung testen, sondern nur aus Erfahrung wissen, was gut funktioniert.

  2. Sei iterativ. Nehmen Sie grundlegende Leistungsmessungen vor, wenn das System relativ neu ist, und testen Sie sie gelegentlich erneut, um sicherzustellen, dass der neu eingeführte Code die Leistung nicht zu stark beeinträchtigt.

  3. Überoptimieren Sie nicht früh. Sie wissen nie, was wichtig sein wird und was nicht wichtig sein wird. Ein superschneller String-Parsing-Algorithmus hilft möglicherweise nicht, wenn Ihr Programm beispielsweise ständig auf E/A wartet.

  4. Insbesondere in Webanwendungen können Sie sich weniger auf die Leistung als auf die Skalierbarkeit konzentrieren. Wenn die Anwendung skaliert werden kann, spielt die Leistung fast keine Rolle, da Sie Ihrer Farm so lange Knoten hinzufügen können, bis sie schnell genug ist.

  5. Besonderes Augenmerk gilt der Datenbank. Aufgrund von Einschränkungen der Transaktionsintegrität ist die Datenbank in der Regel ein Engpass, der jeden Teil des Systems beherrscht. Wenn Sie ein Hochleistungssystem benötigen, stellen Sie sicher, dass Sie talentierte Mitarbeiter auf der Datenbankseite haben, Abfragepläne überprüfen und Tabellen- und Indexstrukturen entwickeln, die gemeinsame Vorgänge so effizient wie möglich gestalten.

Die meisten dieser Aktivitäten sind nicht für den Anfang oder das Ende des Projekts vorgesehen, sondern müssen kontinuierlich durchgeführt werden.

3
John Wu

Ich bin vielleicht voreingenommen, wenn ich in sehr leistungskritischen Bereichen wie Bildverarbeitung und Raytracing arbeite, aber ich würde trotzdem sagen, "so spät wie möglich" zu optimieren. Unabhängig davon, wie leistungskritisch Ihre Anforderungen sind, gibt es im Nachhinein nach der Messung immer so viel mehr Informationen und Klarheit als im Voraus, was bedeutet, dass selbst die effektivsten Optimierungen in der Regel später angewendet werden, nachdem Sie sich dieses Wissen angeeignet haben.

Besondere Fälle

Aber manchmal "so spät wie möglich" ist noch ziemlich früh dran einige besondere Fälle. Wenn es sich zum Beispiel um Offline-Renderer handelt, sind die Datenstrukturen und -techniken, mit denen Sie Leistung erzielen, tatsächlich in das User-End-Design eingedrungen. Dies mag ekelhaft klingen, aber das Feld ist so innovativ und leistungskritisch, dass Benutzer Steuerelemente auf Benutzerseite akzeptieren, die für die für einen bestimmten Raytracer geltenden Optimierungstechniken spezifisch sind (z. B. Bestrahlungs-Caching oder Photonen-Mapping), da einige von ihnen verwendet werden bis Stunden warten, bis ein Bild gerendert ist, und andere sind es gewohnt, enorme Geldsummen auszugeben, um eine Renderfarm mit Maschinen für das Rendern zu mieten oder zu besitzen. Es gibt eine massive Reduzierung von Zeit und Geld für diese Benutzer, wenn ein wettbewerbsfähiger Offline-Renderer eine nicht triviale Reduzierung des Rendering-Zeitraums bieten kann. Dies ist eine Art Bereich, in dem eine Verkürzung der Zeit um 5% die Benutzer tatsächlich begeistert.

In solchen besonderen Fällen können Sie nicht einfach eine Rendering-Technik auswählen und hoffen, sie später zu optimieren, da sich das gesamte Design, einschließlich des User-End-Designs, um die von Ihnen verwendeten Datenstrukturen und Algorithmen dreht. Sie können nicht unbedingt einfach mit dem arbeiten, was für andere Menschen gut funktioniert hat, da Sie als Einzelperson und Ihre besonderen Stärken und Schwächen maßgeblich zur Bereitstellung einer wettbewerbsfähigen Lösung beitragen. Die Denkweise und Sensibilität des Hauptentwicklers hinter Arnold unterscheidet sich von denen, die an VRay arbeiten und einen ganz anderen Ansatz verfolgen. Sie können nicht unbedingt Orte/Techniken tauschen und den besten Job machen (obwohl sie beide Industrieführer sind). Sie müssen experimentieren, Prototypen erstellen und Benchmarks erstellen und herausfinden, was Sie angesichts der endlosen Vielfalt an Spitzentechniken besonders gut können, wenn Sie etwas Wettbewerbsfähiges liefern möchten, das sich tatsächlich verkaufen lässt. In diesem besonderen Fall rücken Leistungsprobleme als vielleicht wichtigstes Problem in den Vordergrund, bevor überhaupt mit der Entwicklung begonnen wird.

Trotzdem ist das nicht unbedingt ein Verstoß gegen die Optimierung von "so spät wie möglich", es ist nur "so spät wie möglich" ist in diesen extremen und besonderen Fällen ziemlich früh . Es ist wahrscheinlich die größte Herausforderung für den Entwickler, herauszufinden, wann und was nicht, wenn überhaupt, solche frühen Leistungsprobleme zu lösen. Was nicht zu optimieren ist, ist möglicherweise eines der wertvollsten Dinge, die man in der Karriere eines Entwicklers lernen und weiter lernen kann, da es nicht an naiven Entwicklern mangelt, die alles optimieren möchten (und leider sogar an einigen Veteranen, die es irgendwie geschafft haben, ihren Job zu behalten trotz ihrer Gegenproduktivität).

So spät wie möglich

Am schwierigsten ist es vielleicht zu verstehen, was es bedeutet. Ich lerne noch und programmiere seit fast drei Jahrzehnten. Aber gerade jetzt in meinem dritten Jahrzehnt wird mir klar, dass es nicht so schwierig ist. Es ist keine Raketenwissenschaft, wenn Sie sich mehr auf Design als auf Implementierung konzentrieren. Je mehr Ihre Designs später Raum für entsprechende Optimierungen lassen, ohne das Design zu ändern, desto später können Sie optimieren. Und je mehr Produktivität ich bei der Suche nach solchen Designs gewonnen habe, die mir diesen Raum zum Atmen bieten.

Design, das Raum zum Atmen bietet, um später zu optimieren

Diese Arten von Designs sind in den meisten Fällen nicht so schwer zu erreichen, wenn wir einen "gesunden Menschenverstand" anwenden können. Als persönliche Geschichte beschäftige ich mich mit bildender Kunst als Hobby (ich finde es etwas hilfreich, Software für Künstler zu programmieren, die selbst etwas sind, um ihre Bedürfnisse zu verstehen und ihre Sprache zu sprechen), und ich habe Anfang der 2000er Jahre einige Zeit mit Oekaki-Applets verbracht Online als schnelle Möglichkeit, meine Arbeit zu kritzeln, zu teilen und mit anderen Künstlern in Kontakt zu treten.

Insbesondere meine Lieblingsseite und mein dortiges Applet waren mit Leistungsmängeln behaftet (jede nicht triviale Pinselgröße würde sich zu einem Crawlen verlangsamen), hatten aber eine sehr nette Community. Um die Leistungsprobleme zu umgehen, habe ich kleine 1- oder 2-Pixel-Pinsel verwendet und meine Arbeit einfach so gekritzelt:

(enter image description here

In der Zwischenzeit gab ich dem Autor der Software Vorschläge zur Verbesserung der Leistung, und er bemerkte, dass meine Vorschläge besonders technischer Natur waren und über Speicheroptimierungen und -algorithmen usw. sprachen. Also fragte er tatsächlich, ob ich ein Programmierer sei und ich sagte ja und er lud mich ein, am Quellcode zu arbeiten.

Also schaute ich mir den Quellcode an, ließ ihn laufen, profilierte ihn und zu meinem Entsetzen hatte er die Software nach dem Konzept einer "abstrakten Pixelschnittstelle" wie IPixel entworfen, die letztendlich die Hauptursache hinter dem war Top-Hotspots für alles mit dynamischen Zuordnungen und Versand für jedes einzelne Pixel jedes einzelnen Bildes. Es gab jedoch keine praktische Möglichkeit, dies zu optimieren, ohne das Design der gesamten Software zu überdenken, da das Design ihn in einer Ecke gefangen hatte, in der es nicht viel über die trivialsten Mikrooptimierungen hinaus gibt, wenn unsere Abstraktionen auf der granularen Ebene eines einzelnen abstrakten Pixels arbeiten und alles hängt von diesem abstrakten Pixel ab. Und so gaben wir die Idee auf, die Software stark zu optimieren, um größere Pinsel und Echtzeitfilter und dergleichen zu handhaben, und ich begann wieder mit 1- oder 2-Pixel-Pinseln zu kritzeln.

Ich denke, das ist eine Verletzung des "gesunden Menschenverstandes", aber offensichtlich war es für den Entwickler kein so gesunder Menschenverstand. Aber es ist so, als würden Sie Dinge nicht auf einer so detaillierten Ebene abstrahieren, dass selbst die grundlegendsten Anwendungsfälle millionenfach instanziiert werden, wie bei Pixeln, Partikeln oder winzigen Einheiten in einer gigantischen Armeesimulation. Bevorzugen Sie IImage (Sie können alle Bild-/Pixelformate verarbeiten, die Sie auf dieser sperrigeren Aggregatebene benötigen) oder IParticleSystem bis IPixel oder IParticle und dann Sie können die grundlegendsten, am schnellsten zu schreibenden und einfach zu verstehenden Implementierungen hinter solchen Schnittstellen einsetzen und haben den nötigen Freiraum, den Sie später für eine Optimierung benötigen, ohne das Design der gesamten Software zu überdenken.

Und das ist das Ziel, wie ich es heutzutage sehe. Ausgenommen die oben genannten besonderen Fälle wie Offline-Renderer: Entwerfen Sie mit genügend Freiraum, um so spät wie möglich zu optimieren, mit möglichst vielen Informationen im Nachhinein (einschließlich Messungen), und wenden Sie alle erforderlichen Optimierungen so spät wie möglich an.

Natürlich schlage ich nicht unbedingt vor, zunächst quadratische Komplexitätsalgorithmen für Eingaben zu verwenden, die in allgemeinen Benutzerendfällen leicht eine nicht triviale Größe erreichen. Wer macht das überhaupt? Aber ich denke nicht einmal, dass das eine so große Sache ist, wenn die Implementierung später einfach auszutauschen ist. Das ist immer noch kein schwerwiegender Fehler, wenn Sie keine Designs überdenken müssen.

1
Dragon Energy

Es ist am einfachsten, Code zu schreiben, der weder porformant noch wartbar ist. Es ist schwieriger, porformanten Code zu schreiben. Es ist noch schwieriger, wartbaren Code zu schreiben. Und es ist am schwierigsten, Code zu schreiben, der sowohl wartbar als auch performant ist.

Es ist jedoch einfacher, wartbaren Code performant zu machen, als performanten Code wartbar zu machen.

Nun hängt es natürlich von der Art des Systems ab, das Sie herstellen. Einige Systeme sind sehr leistungskritisch und müssen von Anfang an geplant werden. Für die äußerst talentierten Leute wie Eric Lippert, die oben geantwortet haben, können diese Systeme üblich sein; Für die meisten von uns sind sie jedoch die Minderheit der Systeme, die wir bauen.

Angesichts des Zustands moderner Hardware ist es jedoch in der Mehrheit der Systeme nicht erforderlich, der Optimierung von Anfang an besondere Aufmerksamkeit zu widmen, sondern vielmehr Vermeidung von Leistungszerstörung ist normalerweise ausreichend. Was ich damit meine, ist, dass Sie es vermeiden, einfach dumme Dinge zu tun, wie alle Datensätze einer Tabelle zurückzubringen, um eine Zählung zu erhalten, anstatt nur select count(*) from table abzufragen. Vermeiden Sie einfach Fehler und bemühen Sie sich, die von Ihnen verwendeten Tools zu verstehen.

Als nächstes konzentrieren Sie sich zunächst darauf, Ihren Code wartbar zu machen. Damit meine ich:

  1. Trennen Sie Bedenken so streng wie möglich (mischen Sie beispielsweise den Datenzugriff nicht mit der Geschäftslogik).
  2. Verweisen Sie nach Möglichkeit auf abstrakte Typen anstelle konkreter Typen
  3. Machen Sie Ihren Code testbar

Wartbarer Code ist viel einfacher zu optimieren, wenn Statistiken zeigen, dass er benötigt wird.

Stellen Sie als Nächstes sicher, dass Ihr Code [~ # ~] viele [~ # ~] automatisierte Tests enthält. Dies hat mehrere Vorteile. Weniger Fehler bedeuten mehr Zeit für die Optimierung bei Bedarf . Wenn Sie optimieren, können Sie die beste Lösung viel schneller iterieren und finden, da Sie Fehler in Ihren Implementierungen viel schneller finden.

Automatisierte Bereitstellungsskripte und eine Skriptinfrastruktur sind auch für die Leistungsoptimierung sehr nützlich, da Sie damit schneller iterieren können. ganz zu schweigen von den anderen Vorteilen.

Wie immer gibt es Ausnahmen (für deren bessere Identifizierung Sie Erfahrung benötigen), aber im Allgemeinen lautet mein Rat: Lernen Sie zuerst Ihre Tools und vermeiden Sie Codierungsengpässe. Stellen Sie zweitens sicher, dass Ihr Code wartbar ist. Drittens automatisierte Tests. Viertens vollautomatische Bereitstellungen. Erst wenn diese Dinge erledigt sind, sollten Sie sich Gedanken über die Optimierung machen.

1
TheCatWhisperer

Ich bin ein Junior-Softwareentwickler und habe mich gefragt, wann der beste Zeitpunkt ist, um eine Software für eine bessere Leistung (Geschwindigkeit) zu optimieren.

Verstehe, dass es zwei sehr unterschiedliche Extreme gibt.

Das erste Extrem sind Dinge, die einen großen Teil des Entwurfs beeinflussen, z. B. wie die Arbeit in wie viele Prozesse und/oder Threads aufgeteilt wird und wie Teile kommunizieren (TCP/IP-Sockets? Direkte Funktionsaufrufe?), Ob eine erweiterte JIT implementiert werden soll oder ein "One Opcode at a Time" -Interpreter oder ob Datenstrukturen so geplant werden sollen, dass sie für SIMD zugänglich sind, oder ... Diese Dinge haben tendenziell einen starken Einfluss auf die Implementierung und werden nachträglich zu schwierig/teuer, um sie nachzurüsten.

Das andere Extrem sind Mikrooptimierungen - winzige kleine Änderungen überall. Diese Dinge haben in der Regel fast keinen Einfluss auf die Implementierung (und werden oft sowieso am besten von einem Compiler ausgeführt), und es ist trivial, diese Optimierungen vorzunehmen, wann immer Sie möchten.

Zwischen diesen Extremen befindet sich eine riesige Grauzone.

Worauf es wirklich ankommt, sind erfahrene/fundierte Vermutungen, die verwendet werden, um die Frage zu beantworten, ob der Nutzen die Kosten rechtfertigt. Für Optimierungen an/in der Nähe eines Extrems, wenn Sie häufig falsch raten, bedeutet dies, dass Sie Ihre gesamte Arbeit wegwerfen und von Grund auf neu starten oder das Projekt fehlschlagen (zu viel Zeit für ein unnötig überkompliziertes Design). Am/in der Nähe des anderen Extrems ist es weitaus sinnvoller, es zu belassen, bis Sie anhand der Messung (z. B. Profilerstellung) nachweisen können, dass es wichtig ist.

Leider leben wir in einer Welt, in der viel zu viele Menschen denken, dass Optimierung nur die (meist irrelevanten) Dinge im "trivialen" Extrem umfasst.

1
Brendan

Dies hängt davon ab, was diese Leistung für Ihre Anwendung bedeutet. Und ob es überhaupt möglich ist, die Leistung zu optimieren, bevor Ihre Anwendung funktionsfähig ist.

Meistens sollten Sie sich keine Sorgen machen, bis Sie nichts Besseres zu tun haben. Es kann jedoch sein, dass ein bestimmtes Leistungsniveau für den Erfolg Ihrer Anwendung entscheidend ist. Wenn dies der Fall wäre und Sie vermuten, dass dies nicht einfach ist, sollten Sie sich die Leistung ansehen, um "schnell zu versagen".

Ein wichtiges Prinzip für jedes Projekt ist es, sich zuerst auf die harten Teile zu konzentrieren. Wenn sich herausstellt, dass Sie dies nicht tun können, werden Sie es frühzeitig wissen und es wird Zeit sein, etwas völlig anderes auszuprobieren, oder das Projekt wird abgebrochen, bevor zu viel dafür ausgegeben wurde.

0
Martin Maat

Ich werde vorschlagen, dass Leistung mehr als Geschwindigkeit ist. Es enthält eine Skalierung (Hunderte bis Tausend gleichzeitige Benutzer). Sicherlich möchten Sie nicht, dass die Anwendung tankt, wenn sie eine Produktionslast erhält. Die Leistung umfasst, wie viel Ressource (z. B. Speicher) die Anwendung verbraucht.

Leistung ist auch einfach zu bedienen. Einige Benutzer möchten lieber, dass 1 Tastendruck eine Aufgabe in 10 Sekunden erledigt, als dass 2 Tastenanschläge die Aufgabe in 1 Sekunde erledigen. Fragen Sie für solche Dinge Ihren Designleiter. Ich mag es nicht, solche Dinge frühzeitig zu den Benutzern zu bringen. In einem Vakuum können sie X sagen, aber sobald sie mit einer funktionalen Vorabversion arbeiten, können sie Y sagen.

Die beste individuelle Geschwindigkeit besteht darin, eine Ressource wie eine Datenbankverbindung zu halten. Für die Skalierung sollten Sie die Verbindung jedoch so spät wie möglich erwerben und so schnell wie möglich freigeben. Eine Reise in die Datenbank, um drei Dinge zu erhalten, ist schneller als drei separate Reisen in die Datenbank.

Machen Sie Reisen zu Informationen, die sich während der Sitzung nicht ändern. Wenn ja, holen Sie es sich beim Start der Sitzung und halten Sie es als Speicher.

Berücksichtigen Sie bei der Auswahl des Sammlungstyps die Funktion, Geschwindigkeit und Größe.

Sind Sie sicher, dass Sie die Artikel in einer Sammlung aufbewahren müssen? Ein häufiges Problem besteht darin, alle Zeilen aus einer Datei in eine Liste einzulesen und die Liste dann zeilenweise zu verarbeiten. Es ist viel effizienter, die Datei zeilenweise zu lesen und die Liste zu überspringen.

Schleifen Sie dreimal, wenn Sie einmal schleifen und drei Dinge tun könnten?.

Gibt es eine Stelle, an der Sie möglicherweise einen anderen Thread mit einem Rückruf bearbeiten müssen? Wenn ja, verpacken Sie den Code unter Berücksichtigung dieses möglichen Bedarfs, wenn er die unmittelbaren Entwurfsanforderungen nicht beeinträchtigt.

Viel Leistung ist auch sauberer Code.

Es gibt eine vorzeitige Optimierung und es gibt nur vernünftige Dinge im Voraus, die nicht wirklich mehr Zeit in Anspruch nehmen.

In der Datenbank sehe ich vorzeitige Optimierung. Wird für die Geschwindigkeit de-normalisiert, bevor ein Geschwindigkeitsproblem auftritt. Das Argument, das ich bekomme, ist, wenn wir die Tabelle später ändern, müssen wir alles ändern. Oft können Sie eine Ansicht erstellen, in der die Daten auf diese Weise dargestellt werden, und sie müssen möglicherweise später gegen eine nicht normalisierte Tabelle ausgetauscht werden.

0
paparazzo

Holen Sie sich zuerst das MVP an den Kunden. Führen Sie dann eine statistische Profilerstellung durch, um festzustellen, was langsam ist.

0
guettli