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


19

Ich bin ein junger Softwareentwickler und habe mich gefragt, wann der beste Zeitpunkt für die Optimierung einer Software für eine bessere Leistung (Geschwindigkeit) ist.

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


7
Gedankenexperiment: Sie wählen eine interpretierte Programmiersprache, um Ihr interaktives Spiel zu entwickeln, und stellen zur Hälfte des Entwicklungsprozesses fest, dass die von Ihnen gewählte Sprache nicht die erforderliche Geschwindigkeit besitzt, um Ihre Frameratenanforderungen zu erfüllen. Bist du königlich beschissen?
Robert Harvey

8
Ein weiteres Gedankenexperiment: Sie optimieren sorgfältig einen Code in Ihrem Spiel, von dem Sie glauben, dass er für die Leistung kritisch ist, führen dann jedoch einen Profiler für den Code aus und stellen fest, dass der von Ihnen optimierte Code keinen wesentlichen Beitrag zur Gesamtleistung leistet verringerte die Klarheit des Codes. Hast du deine Zeit verschwendet?
Robert Harvey

8
Fazit: Handelt es sich um eine Entweder-Oder-Entscheidung, oder ist es möglicherweise wichtig, einige Leistungsentscheidungen frühzeitig zu treffen, während andere aufgeschoben werden?
Robert Harvey

1
Ich tippte und löschte eine Antwort und tippte sie immer wieder ein. Es gibt einfach keine Antwort auf diese Frage, weil es darauf ankommt. In einigen Fällen übertrifft das Ausstoßen eines Produkts alle anderen Überlegungen, in anderen Fällen ist die Optimierung von Anfang an eine schwierige Anforderung und in Millionen anderen Szenarien gilt es, von Anfang an zu optimieren oder gar nicht zu optimieren und was auch immer sonst.
Pieter B

Egal wie du es ansiehst. Am Anfang gibt es nichts zu optimieren, da es nichts zu vergleichen gibt. Sie benötigen noch 2 Referenzen, um etwas zu optimieren: die ideale Leistung (gemäß den Anforderungen) und die echte (die, die Sie erhalten, wenn Sie etwas zum Laufen bringen).
Laiv,

Antworten:


52

Das Wichtigste 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 jemanden fragen, was dies überhaupt tun sollte.

Es ist bemerkenswert, wie performant 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 soll nicht heißen, dass mir die Geschwindigkeit egal ist. Ich mache. Ich habe gerade festgestellt, dass es nur sehr wenige Probleme gibt, deren Lösungen schneller sind, wenn sie schwer lesbar sind.

Nur zwei Dinge bringen mich aus diesem Modus heraus:

  1. Wenn ich eine Chance auf eine vollständige Verbesserung von O sehe , dann auch nur, wenn n groß genug ist, dass es irgendjemand interessieren würde.
  2. Wenn ich Tests habe, die echte Leistungsprobleme zeigen. Trotz jahrzehntelanger Erfahrung vertraue ich den Tests mehr als meiner Mathematik. Und ich kann gut rechnen.

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


Ich habe immer festgestellt, dass das Wichtigste, worauf sich Softwareentwickler konzentrieren sollten, darin besteht, ein Produkt mit einer möglichst hübschen Oberfläche so schnell wie möglich in den Handel zu bringen. Fehler und schlechtes Design können später behoben werden.
Pieter B

12
@PieterB: Es ist bemerkenswert einfach, die Entwicklung durch eine Strategie wie "Fehler und schlechtes Design können später behoben werden" zu verlangsamen . Mit schlechtem Design meine ich Dinge wie unlesbaren, verschachtelten Code sowie überarbeiteten Code.
Doc Brown

5
@Walfrat: Ich denke, Ihr Beispiel kann leicht beschleunigt werden, ohne die Lesbarkeit zu beeinträchtigen, und ich interpretiere diese Antwort nicht als "lesbarer Code weist keine Leistungsprobleme auf", sondern eher als "Leistungsprobleme werden nicht automatisch durch das Erstellen von Code vermieden unleserlich".
Doc Brown

2
@PieterB: oder Sie haben einen Kunden, der sein Geld zurückbekommen möchte, weil das gekaufte Produkt so fehlerhaft ist, dass er es nicht verwenden kann.
Doc Brown

2
@svidgen Die Bewertung der Geschwindigkeit von nicht lesbarem Code ohne Tests ist so gut wie unmöglich. Wenn Sie sich auf die Geschwindigkeit konzentrieren und die Lesbarkeit ignorieren, treten unübersehbare Geschwindigkeitsprobleme auf. Wenn Sie sich auf die Lesbarkeit konzentrieren, werden Geschwindigkeitsprobleme so offensichtlich, dass Sie nicht mehr darüber nachdenken müssen. Sie werden es sehen, sobald Sie es schreiben. Selbst wenn Sie dies nicht tun, können Sie das Problem finden, sobald Sie es mindestens einmal getestet haben. Warum sollte man bei alledem standardmäßig auf Schnelligkeit und Lesbarkeit achten? Wenn Sie sich auf Geschwindigkeit konzentrieren und die Lesbarkeit ignorieren, erhalten Sie keine.
candied_orange

27

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

Im Allgemeinen ist es jedoch nicht möglich, eine Optimierung vorzunehmen, bevor der Code geschrieben wurde: Lassen Sie ihn erst funktionieren, dann richtig und zuletzt schnell .

Ein großes Problem bei der Optimierung vor der Implementierung der meisten Funktionen besteht darin, dass Sie sich an den falschen Stellen in nicht optimale Entwurfsentscheidungen verstrickt 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 Hot Spots, die es wirklich wert sind, optimiert zu werden. Die Wartbarkeit für die Leistung an all jenen Orten zu opfern, die keine Leistung benötigen, ist ein wirklich schlechter Handel.

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


15

Wann ist 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, aus Ihrem Kopf. Leistung ist das, was der Benutzer für Leistung hält .

Wenn eine Anwendung auf einen Mausklick doppelt so schnell reagiert und Sie von zehn Mikrosekunden auf fünf Mikrosekunden wechseln, ist es dem Benutzer egal. Wenn Sie eine Anwendung dazu bringen, doppelt so schnell auf einen Mausklick zu reagieren, und Sie von viertausend auf zweitausend Jahre wechseln, ist es dem Benutzer ebenfalls egal.

Wenn Sie Ihre Anwendung doppelt so schnell erstellen und den gesamten Arbeitsspeicher des Computers belegen und abstürzen, ist es dem Benutzer egal, dass sie jetzt doppelt so schnell ist.

Leistung ist die Wissenschaft von effektiven Kompromissen beim Ressourcenverbrauch, 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 oft Zeit gegen Raum oder umgekehrt aus.

Vorausgesetzt, die Software ist nicht extrem umfangreich und komplex in der Verwaltung

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 dann mit der Optimierung fortfahren, um eine bessere Leistung zu erzielen?

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, es in einer anderen Reihenfolge zu tun, werden Sie mit falschem Code konfrontiert, und jetzt haben Sie ein Programm, das sehr schnell falsche Antworten liefert und Änderungen widersteht.

Aber da fehlt ein Schritt. Die richtige Reihenfolge ist:

  • Arbeiten Sie mit Kunden und dem 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 Test-Gurtzeug, 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. Nutze die 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 versuchen Sie es später erneut.
  • Mach es richtig
  • Führen Sie die Tests erneut aus ...
  • Mach es elegant
  • Führen Sie die Tests erneut aus ...
  • Entsprechen Sie Ihrem Ziel? Wenn ja, geh zum Strand . Wenn nicht, mach es schnell genug .

"Leistung ist das, was der Benutzer für Leistung hält." - ja, irgendwann die User Experience ist eigentlich besser , wenn Dinge , die wir erwarten , Zeit zu nehmen , tun einige Zeit dauern: webdesignerdepot.com/2017/09/when-slower-ux-is-better-ux
svidgen

vielleicht "wissenschaftlich sein" anstatt "Wissenschaft nutzen" :)
blau

@svidgen: Ich erinnere mich, dass ich meinen Code einmal geändert habe, um einen Fortschrittsbalken zu verlangsamen. Die Nutzer hatten den Eindruck, dass echte Arbeit geleistet wurde und waren damit zufrieden. Die berechnete Funktion war nützlich, aber es sah so aus, als würde das Programm nichts tun, wenn das Ergebnis nach einer Zehntelsekunde da wäre.
Giorgio

2
@Giorgio: Das ist mein Datum, aber ich erinnere mich, als ich zum ersten Mal eine Festplatte bekam und ein Spiel oder ein Dokument speicherte und dachte, dass etwas schief gelaufen war, weil der Vorgang im Vergleich zum Speichern auf Diskette keine nennenswerte Zeit in Anspruch nahm. Und natürlich sind der Spielstatus und die Dokumente jetzt so groß, dass wir wieder Zeit sparen können.
Eric Lippert

3

In der Regel ist es am besten, die Leistung später zu optimieren, aber ich habe festgestellt, dass viele Projekte schlecht laufen, wenn Entwickler feststellen, dass sie Software haben, die zu langsam ist, wenn signifikante Lasten 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 insgesamt.

Ich gebe ein Beispiel, das ich oft gesehen habe; Bei einer gegebenen 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 enthält (aber viel, viel mehr beinhalten kann), dann durchlaufen wir die Aufträge, einschließlich des Abrufs aller relevanten Daten für alle Auftragspositionen des Auftrags , Produktinformationen usw. - alles nur, um für jede Bestellung eine einzige Ganzzahl zu erhalten!

Die Menge an SQL-Abfragen hier könnte Sie überraschen. Natürlich hängt es davon ab, wie Ihre Entitäten strukturiert sind.

Hier wäre der richtige Ansatz wahrscheinlich, 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. Ich würde empfehlen, dies beim ersten Mal zu tun und dies nicht zu verschieben für später; Denn wenn Sie dies tun, werden Sie wahrscheinlich noch viel mehr Probleme haben, um die Sie sich kümmern müssen, und Sie sind sich nicht sicher, wo Sie anfangen sollen.


3

Die Gesamtsystemleistung ist ein Produkt der komplexen Wechselwirkungen der Gesamtheit der Systemkomponenten. Es ist ein nichtlineares System. Daher hängt die Leistung nicht nur von der individuellen Leistung der Komponenten ab, sondern auch von den Engpässen zwischen den Komponenten .

Offensichtlich können Sie nicht auf Engpässe testen, wenn noch nicht alle Komponenten Ihres Systems erstellt wurden. Daher können Sie frühzeitig keine guten Tests durchführen. Andererseits fällt es Ihnen nach der Erstellung des Systems möglicherweise nicht so leicht, die Änderungen vorzunehmen, die Sie vornehmen müssen, um die gewünschte Leistung zu erzielen. Das ist also ein echter Catch-22 .

Um die Angelegenheit 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 als "Best Practice" für die Leistung gelten. Verwenden Sie beispielsweise Verbindungspools, asynchrone Transaktionen und die Vermeidung von Zuständen. Dies kann zum Tod einer Multithread-Anwendung führen, bei der verschiedene Worker um den Zugriff auf gemeinsam genutzte Daten kämpfen. Normalerweise würden Sie diese Muster nicht auf Leistung testen, Sie würden nur aus Erfahrung wissen, was gut funktioniert.

  2. Sei iterativ. Ergreifen Sie grundlegende Leistungsmessungen, wenn das System relativ neu ist, und wiederholen Sie gelegentlich den Test, um sicherzustellen, dass der neu eingeführte Code die Leistung nicht zu stark beeinträchtigt.

  3. Überoptimieren Sie nicht zu früh. Man weiß nie, was wichtig sein wird und was nicht wichtig sein wird. Ein superschneller String-Parsing-Algorithmus hilft möglicherweise nicht weiter, 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 der 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 besteht die Tendenz, dass die Datenbank ein Engpass ist, der jeden Teil des Systems dominiert. Wenn Sie ein hochleistungsfähiges System benötigen, sollten Sie sicherstellen, dass talentierte Mitarbeiter auf der Datenbankseite arbeiten, die Abfragepläne überprüfen und Tabellen- und Indexstrukturen entwickeln, um die allgemeinen Vorgänge so effizient wie möglich zu gestalten.

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


1

Ich bin ein junger Softwareentwickler und habe mich gefragt, wann der beste Zeitpunkt für die Optimierung einer Software für eine bessere Leistung (Geschwindigkeit) ist.

Verstehen Sie, dass es zwei sehr unterschiedliche Extreme gibt.

Das erste Extrem sind Dinge, die einen großen Teil des Designs beeinflussen, wie die Aufteilung der Arbeit in wie viele Prozesse und / oder Threads und wie Teile kommunizieren (TCP / IP-Sockets? Direkte Funktionsaufrufe?), Ob eine erweiterte JIT implementiert werden soll oder ein "ein Opcode nach dem anderen" -Interpreter, oder ob Datenstrukturen so geplant werden sollen, dass sie für SIMD zugänglich sind, oder ... Diese Dinge haben in der Regel einen starken Einfluss auf die Implementierung und sind nachträglich übermäßig schwierig / teuer 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 dies wünschen.

Dazwischen befindet sich eine riesige Grauzone.

Worauf es wirklich ankommt, ist, dass Erfahrungen / Vermutungen herangezogen werden, um die Frage zu beantworten, ob die Vorteile die Kosten rechtfertigen. Für Optimierungen an / in der Nähe eines Extrems, wenn Sie häufig falsch raten, bedeutet dies, dass Sie Ihre gesamte Arbeit aufgeben und von vorne beginnen oder das Projekt scheitern (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 von Messungen (z. B. Profilerstellung) beweisen können, dass es darauf ankommt.

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


1

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 leistungsfähig zu machen, als leistungsfähigen 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 benötigen das von Anfang an Geplante. Für die extrem talentierten Leute wie Eric Lippert, die oben geantwortet haben, sind diese Systeme möglicherweise weit verbreitet. Für die meisten von uns sind sie jedoch die Minderheit der Systeme, die wir bauen.

Angesichts des Standes der modernen Hardware ist es jedoch in den meisten Systemen nicht erforderlich, von Anfang an ein besonderes Augenmerk auf die Optimierung zu legen, sondern es ist in der Regel ausreichend , Leistungseinbußen zu vermeiden . Was ich damit meine, ist, dass Sie es vermeiden sollten, einfach nur dumme Dinge zu tun, wie zum Beispiel alle Datensätze einer Tabelle zurückzubringen, um eine Zählung zu erhalten, anstatt nur abzufragen select count(*) from table. 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, wo möglich, auf abstrakte Typen anstatt auf konkrete Typen
  3. Machen Sie Ihren Code testbar

Wartungsfähiger 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 Bugs bedeuten mehr Zeit für die Optimierung bei Bedarf . Wenn Sie optimieren, können Sie außerdem viel schneller iterieren und die beste Lösung finden, da Sie Fehler in Ihren Implementierungen viel schneller finden.

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

Es gibt also wie immer Ausnahmen (für deren Identifizierung Sie Erfahrung benötigen), aber im Allgemeinen lautet mein Rat: Lernen Sie zunächst Ihre Tools kennen und vermeiden Sie Engpässe bei der Programmierleistung. 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

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

Besondere Fälle

Aber manchmal ist "so spät wie möglich" in einigen besonderen Fällen immer noch verdammt früh. Wenn es sich beispielsweise um Offline-Renderer handelt, fließen die Datenstrukturen und -techniken, mit denen Sie Leistung erzielen, tatsächlich in das Design für Benutzer ein. Dies mag ekelhaft klingen, aber das Feld ist so aktuell und so leistungskritisch, dass Benutzer benutzerspezifische Steuerelemente akzeptieren, die für die für einen bestimmten Raytracer geltenden Optimierungstechniken (z. B. Caching der Bestrahlungsstärke oder Photonenzuordnung) spezifisch sind, da einige von ihnen verwendet werden Es ist gewohnt, stundenlang auf das Rendern eines Bildes zu warten, und andere sind es gewohnt, enorme Geldsummen für die Miete oder den Besitz einer Renderfarm mit Geräten für das Rendern auszugeben. Für diese Benutzer bedeutet dies eine erhebliche Zeit- und Geldersparnis, wenn ein wettbewerbsfähiger Offline-Renderer eine nicht unerhebliche Reduzierung des Zeitaufwands für das Rendern bieten kann. Dies ist eine Art Bereich, in dem eine Zeitersparnis von 5% die Benutzer tatsächlich begeistert.

In solchen besonderen Fällen können Sie nicht einfach eine Rendering-Technik auswählen und hoffen, diese später zu optimieren, da sich das gesamte Design, einschließlich des benutzerseitigen Designs, auf die von Ihnen verwendeten Datenstrukturen und Algorithmen konzentriert. Sie können nicht unbedingt einfach das tun, was für andere Menschen gut funktioniert hat, da Sie als Einzelperson und Ihre besonderen Stärken und Schwächen entscheidend dazu beitragen, eine wettbewerbsfähige Lösung zu finden. Die Einstellung 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, einen Prototyp und einen Benchmark erstellen und herausfinden, was Sie suchen. Es ist besonders gut, wenn man bedenkt, dass es eine endlose Reihe von Spitzentechniken gibt, wenn man hofft, etwas Wettbewerbsfähiges zu liefern, das sich tatsächlich verkaufen wird. In diesem besonderen Fall rücken die Leistungsbedenken als vielleicht wichtigste Bedenken vor Beginn der Entwicklung in den Vordergrund.

Dies ist jedoch nicht unbedingt eine Verletzung der Optimierung von "so spät wie möglich" , sondern "so spät wie möglich" ist in diesen extremen und besonderen Fällen eher früh. Wenn überhaupt, ist es wahrscheinlich die größte Herausforderung für den Entwickler, herauszufinden, wann und was solche frühen Performance-Bedenken nicht benötigt. Was man nicht optimieren sollte, 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 auch an Veteranen, die es irgendwie geschafft haben, ihren Job zu behalten) trotz ihrer Kontraproduktivität).

So spät wie möglich

Vielleicht ist es am schwierigsten zu verstehen, was es bedeutet. Ich lerne noch und programmiere seit fast drei Jahrzehnten. Aber gerade jetzt in meinem dritten Jahrzehnt beginne ich zu erkennen, dass es nicht so schwierig ist. Es ist keine Hexerei, wenn Sie sich mehr auf Design als auf Implementierung konzentrieren. Je mehr Ihre Entwürfe später ohne Änderungen am Entwurf Freiraum für entsprechende Optimierungen lassen, desto später können Sie optimieren. Und je produktiver ich geworden bin, desto mehr habe ich nach solchen Designs gesucht, die mir den nötigen Freiraum bieten.

Entwerfen Sie, welche Atempause bieten, um später zu optimieren

Diese Arten von Designs sind in den meisten Fällen gar nicht so schwer zu realisieren, 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 zu programmieren, damit Künstler ihre Bedürfnisse verstehen und ihre Sprache sprechen können), 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 Lieblings-Site und mein Lieblings-Applet waren mit Leistungsmängeln übersät (jede nicht triviale Pinselgröße würde zu einem Crawl verlangsamen), hatten aber eine sehr nette Community. Um die Performance-Probleme zu umgehen, habe ich kleine 1 oder 2-Pixel-Pinsel verwendet und meine Arbeit einfach so gekritzelt:

Bildbeschreibung hier eingeben

In der Zwischenzeit gab ich dem Autor der Software Vorschläge zur Leistungsverbesserung und er bemerkte, dass meine Vorschläge besonders technischer Natur waren und sich mit Speicheroptimierungen und Algorithmen usw. befassten. Also fragte er tatsächlich, ob ich ein Programmierer sei und ich sagte ja und er lud mich ein, am Quellcode zu arbeiten.

Also habe ich mir den Quellcode angesehen, ihn ausgeführt, profiliert und zu meinem Entsetzen die Software nach dem Konzept einer "abstrakten Pixelschnittstelle" entworfen IPixel, die letztendlich die Ursache hinter den Top-Hotspots für alles mit Dynamik war Zuweisungen 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 eine Ecke geführt hatte, in der es kaum etwas Außergewöhnliches gibt, wenn unsere Abstraktionen auf der granularen Ebene eines einzelnen abstrakten Pixels arbeiten und alles hängt von diesem abstrakten Pixel ab.

Ich denke, das ist eine Verletzung des "gesunden Menschenverstandes", aber offensichtlich war es für den Entwickler nicht so vernünftig. Aber es ist so, als ob Sie keine abstrakten Dinge auf solch einer granularen Ebene machen, bei der selbst die grundlegendsten Anwendungsfälle millionenfach instanziiert werden, wie bei Pixeln oder Partikeln oder winzigen Einheiten in einer gigantischen Armeesimulation. Favor die IImage(Sie alle das Bild / Pixelformate , die Sie in dieser sperrigen aggregierter Ebene müssen umgehen können) oder IParticleSysteman IPixeloder IParticle, und dann können Sie in den grundlegendsten setzen und schnell zu schreiben und einfach zu verstehende Implementierungen hinter solchen Schnittstellen und Sie haben den ganzen Freiraum, den Sie später optimieren müssen, ohne das Design der gesamten Software zu überdenken.

Und das ist das Ziel, wie ich es heutzutage sehe. Ausgenommen der besonderen Fälle, wie die oben genannten Offline-Renderer, sollten Sie so viel Freiraum für eine spätestmögliche Optimierung mit möglichst vielen Informationen im Nachhinein (einschließlich Messungen) bereitstellen und die erforderlichen Optimierungen so spät wie möglich durchführen.

Natürlich schlage ich nicht unbedingt vor, mit der Verwendung von Algorithmen mit quadratischer Komplexität für Eingaben zu beginnen, die in allgemeinen Fällen für Benutzer leicht eine nicht triviale Größe erreichen. Wer macht das schon? Aber ich denke nicht, dass das so eine große Sache ist, wenn die Implementierung später einfach ausgetauscht werden kann. Das ist immer noch kein schwerer Fehler, wenn Sie keine Entwürfe überdenken müssen.


0

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.

In den meisten Fällen sollten Sie sich darüber keine Gedanken 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 ist und Sie vermuten, dass es nicht einfach ist, sollten Sie die Leistung überprüfen, um "schnell zu scheitern".

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


0

Ich werde vorschlagen, dass Leistung mehr als Geschwindigkeit ist. Es umfasst Skalierung (Hunderte bis Tausende gleichzeitiger Benutzer). Sie möchten sicher nicht, dass die Anwendung beim Erreichen einer Produktionslast den Tank füllt. Die Leistung umfasst, wie viel Ressource (z. B. Speicher) die Anwendung verbraucht.

Leistung ist auch Benutzerfreundlichkeit. Einige Benutzer möchten lieber, dass 1 Tastendruck eine Aufgabe in 10 Sekunden ausführt, als dass 2 Tastenanschläge die Aufgabe in 1 Sekunde ausführen. Für solche Sachen fragen Sie Ihren Designleiter. Ich mag es nicht, solche Dinge frühzeitig an Benutzer weiterzugeben. In einem Vakuum können sie X sagen, aber sobald sie mit einer funktionalen Vorfreigabe 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 sie so bald wie möglich freigeben. Ein Trip in die Datenbank, um drei Dinge zu erhalten, ist schneller als drei separate Trips in die Datenbank.

Machen Sie Ausflüge zu Informationen, die sich während der Sitzung nicht ändern? Wenn ja, holen Sie es sich beim Sitzungsstart und halten Sie es in Erinnerung.

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

Müssen Sie die Objekte wirklich in einer Sammlung aufbewahren? Ein häufiges Problem besteht darin, alle Zeilen 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.

Spielen Sie dreimal in einer Schleife, wenn Sie einmal in einer Schleife arbeiten und drei Dinge tun konnten?

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

Eine Menge Leistung ist auch sauberer Code.

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

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.