Ich habe kürzlich eine Frage zu Stack Overflow gestellt, um herauszufinden, warum isset () in PHP schneller war als strlen () . Dies warf Fragen zur Wichtigkeit von lesbarem Code auf und ob Leistungsverbesserungen von Mikrosekunden im Code überhaupt in Betracht gezogen werden sollten.
Mein Vater ist ein pensionierter Programmierer, und ich habe ihm die Antworten gezeigt. Er war sich absolut sicher, dass ein Kodierer keine guten Programmierer sind, wenn er die Leistung in seinem Code selbst auf Mikroebene nicht berücksichtigt.
Ich bin mir nicht so sicher - vielleicht bedeutet die Erhöhung der Rechenleistung, dass wir diese Art von Verbesserungen der Mikro-Performance nicht mehr in Betracht ziehen müssen? Vielleicht liegt diese Art der Überlegung bei den Leuten, die den eigentlichen Sprachcode schreiben? (von PHP im obigen Fall).
Die Umweltfaktoren könnten wichtig sein - das Internet verbraucht 10% der weltweiten Energie. Ich frage mich, wie verschwenderisch ein paar Mikrosekunden Code sind, wenn er millionenfach auf Websites repliziert wird.
Ich möchte Antworten wissen, die vorzugsweise auf Fakten zur Programmierung basieren.
Ist die Mikrooptimierung beim Codieren wichtig?
Meine persönliche Zusammenfassung von 25 Antworten, danke an alle.
Manchmal müssen wir uns wirklich um Mikrooptimierungen kümmern, aber nur in sehr seltenen Fällen. Zuverlässigkeit und Lesbarkeit sind in den meisten Fällen weitaus wichtiger. Es tut jedoch nicht weh, von Zeit zu Zeit eine Mikrooptimierung in Betracht zu ziehen. Ein grundlegendes Verständnis kann uns helfen, keine offensichtlichen Fehlentscheidungen bei der Codierung zu treffen, wie z
if (expensiveFunction() || counter < X)
Sollte sein
if (counter < X || expensiveFunction())
( Beispiel von @ zidarsk8 ) Dies könnte eine kostengünstige Funktion sein und daher wäre das Ändern des Codes eine Mikrooptimierung . Aber mit einem grundlegenden Verständnis müssten Sie nicht, weil Sie es an erster Stelle richtig schreiben würden.
coder does not consider performance in their code even at the micro level, they are not good programmers
unterscheidet sich stark von der Mikrooptimierung. Es ist nur eine gute Codierung.Antworten:
Ich stimme deinem Vater zu und stimme ihm nicht zu. Über die Leistung sollte früh nachgedacht werden, aber über die Mikrooptimierung sollte nur früh nachgedacht werden, wenn Sie tatsächlich wissen, dass ein hoher Prozentsatz der Zeit in kleinen CPU-gebundenen Codeabschnitten verbracht wird.
Das Problem bei der Mikrooptimierung besteht darin, dass in der Regel keine Vorstellung davon besteht, wie Programme tatsächlich mehr Zeit als erforderlich verbringen.
Dieses Wissen stammt aus der Erfahrung mit der Leistungsoptimierung, wie in diesem Beispiel , in dem ein scheinbar einfaches Programm ohne offensichtliche Ineffizienzen durch eine Reihe von Diagnose- und Beschleunigungsschritten geführt wird, bis es 43-mal schneller als zu Beginn ist.
Was es zeigt, ist, dass Sie nicht wirklich erraten oder verstehen können, wo die Probleme liegen werden. Wenn Sie eine Diagnose durchführen, bei der es sich in meinem Fall um eine zufällige Pause handelt , werden Codezeilen, die für einen erheblichen Teil der Zeit verantwortlich sind, bevorzugt freigelegt. Wenn Sie sich diese ansehen, finden Sie möglicherweise Ersatzcode und reduzieren dadurch die Gesamtzeit um ungefähr diesen Bruchteil.
Andere Dinge, die Sie nicht repariert haben, benötigen immer noch so viel Zeit wie zuvor, aber da sich die Gesamtzeit verringert hat, benötigen diese Dinge jetzt einen größeren Bruchteil. Wenn Sie also alles noch einmal machen, kann dieser Bruchteil auch beseitigt werden. Wenn Sie dies über mehrere Iterationen hinweg tun, können Sie massive Beschleunigungen erzielen, ohne jemals eine Mikrooptimierung durchgeführt zu haben .
Wenn Sie sich nach dieser Erfahrung neuen Programmierproblemen nähern, erkennen Sie die Konstruktionsansätze, die anfänglich zu solchen Ineffizienzen führen. Nach meiner Erfahrung kommt es von einem Überdesign der Datenstruktur, einer nicht normalisierten Datenstruktur, einem massiven Vertrauen in Benachrichtigungen und dergleichen.
quelle
Mikrooptimierung ist nur wichtig, wenn die Zahlen es aussagen.
Für die Anforderungen, gegen die Sie sich entwickeln, sollten einige Leistungsdaten angegeben werden, wenn die Leistung für den Client oder den Benutzer überhaupt ein Problem darstellt. Während Sie Software entwickeln, sollten Sie die Leistung Ihres Systems anhand dieser Anforderungen testen. Wenn Sie die Leistungsanforderungen nicht erfüllen, müssen Sie Ihre Codebasis profilieren und nach Bedarf optimieren, um die Leistungsanforderungen zu erreichen. Sobald Sie die erforderliche Mindestleistung erreicht haben, müssen Sie keine Leistung mehr aus dem System herausholen, insbesondere wenn Sie die Lesbarkeit und Wartbarkeit des Codes nicht mehr beeinträchtigen (nach meiner Erfahrung ist hochoptimierter Code weniger lesbar und fehlerhaft) wartbar, aber nicht immer). Wenn Sie zusätzliche Leistungssteigerungen erzielen können, ohne die anderen Qualitätsmerkmale des Systems zu beeinträchtigen,
Es gibt jedoch Fälle, in denen die Leistung von größter Bedeutung ist. Ich denke hauptsächlich an Echtzeitsysteme und eingebettete Systeme. In Echtzeitsystemen kann eine Änderung der Betriebsreihenfolge einen enormen Einfluss auf die Einhaltung der für einen ordnungsgemäßen Betrieb erforderlichen harten Fristen haben und möglicherweise sogar die Ergebnisse von Berechnungen beeinflussen. In eingebetteten Systemen ist der Arbeitsspeicher, die CPU-Leistung und die Leistung (wie bei der Akkuleistung) normalerweise begrenzt. Daher müssen Sie die Größe Ihrer Binärdateien und die Anzahl der Berechnungen reduzieren, um die Systemlebensdauer zu maximieren.
quelle
Wann immer jemand nach Optimierung fragt , werde ich an das Zitat von Michael A. Jackson erinnert
Zitat aus Wikipedia korrigiert für britisches Englisch. * 8 ')
Die zweite Regel impliziert, dass Sie Ihr Code- Profil erstellen und nur Zeit damit verbringen, Dinge zu optimieren, die den Unterschied ausmachen.
Bei der Programmierung in der Baugruppe stimmte die Aussage Ihres Vaters. Aber das ist dem Metal viel näher, als die meisten Leute heutzutage programmieren. Heutzutage kann sogar der Versuch , sich selbst zu optimieren (ohne Profilerstellung), dazu führen, dass Ihr Code langsamer ausgeführt wird, als wenn Sie etwas auf die üblichere Weise getan hätten, da es wahrscheinlicher ist, dass der übliche Weg von modernen JIT- Compilern optimiert wird .
Sogar in C muss man ziemlich gut optimieren können, um mehr darüber zu wissen, wie man einen Codeabschnitt optimiert als der Compiler.
Wenn Sie nicht viel über das wissen , worüber Ulrich Drepper in seinem exzellenten Artikel Was jeder Programmierer über Speicher wissen sollte , dann sind Sie wahrscheinlich auf einem Verlierer, der sogar versucht, sich selbst zu optimieren. Im Gegensatz zum Titel der Arbeit (der eigentlich eine Hommage an David Goldbergs gleichermaßen fantastisches Wissen über Gleitkomma-Arithmetik ist ) bedeutet ein solches Verständnis jedoch nicht zwangsläufig, dass Sie ein guter Programmierer sind, sondern eine andere Art von Programmierer Programmierer.
isset()
vs.strlen()
in PHPIch kenne PHP nicht, es ist also nicht klar, was
isset()
damit gemeint ist. Ich kann es aus dem Kontext ableiten, aber dies bedeutet, dass es für unerfahrene PHP-Programmierer ähnlich undurchsichtig sein wird und sogar erfahrene Programmierer dazu veranlassen könnte, zweimal zu arbeiten. Dies ist die Art der idiomatischen Verwendung einer Sprache, die die Wartung zu einem Albtraum machen kann.Darüber hinaus gibt es keine Garantie,
isset()
die immer effizienter sein wird, nur weil sie jetzt effizienter ist. Eine Optimierung ist jetzt möglicherweise keine Optimierung im nächsten Jahr oder in 10 Jahren. CPUs, Systeme, Compiler verbessern sich und ändern sich im Laufe der Zeit. Wenn die Leistung von PHPstrlen()
ein Problem darstellt, wird PHP möglicherweise in Zukunft geändert, und alle isset () -Optimierungen müssen möglicherweise entfernt werden, um den Code erneut zu optimieren.Jede Optimierung hat das Potenzial, eine zukünftige Anti-Optimierung zu werden. Daher sollte ein möglicher Code-Geruch in Betracht gezogen werden, um das Risiko so gering wie möglich zu halten.
Ein Beispiel aus eigener Erfahrung
Als Beispiel für eine solche Anti-Optimierung musste ich einmal eine riesige Codebasis bereinigen, die mit Code des Formulars gefüllt war,
if x==0 z=0 else z=x*y
weil jemand die Annahme gemacht hatte, dass eine Gleitkomma-Multiplikation immer teurer sein würde als eine Verzweigung. Bei der ursprünglichen Zielarchitektur führte diese Optimierung dazu, dass der Code eine Größenordnung schneller ausgeführt wurde, die Zeiten sich jedoch änderten.Als wir versuchten, diesen Code auf einer moderneren CPU zu verwenden, die eine hohe Pipeline-Auslastung aufwies, war die Leistung furchtbar schlecht - jede dieser Anweisungen führt zu einem Pipeline-Flush. Durch die Vereinfachung all dieser Codezeilen konnte
z=x*y
das Programm auf der neuen Architektur um eine Größenordnung schneller ausgeführt werden und die durch die Antioptimierung verlorene Leistung wiederhergestellt werden .Die Probleme , die wir haben in der Regel für heute zu optimieren , sind sehr unterschiedlich zu denen , die wir vor 20 oder sogar 10 Jahren gehabt zu optimieren.
Dann wir besorgt über die meiste Arbeit pro Taktzyklus zu tun, jetzt sind wir eher über Pipeline Wallungen sein besorgniserregend, Verzweigungsfehlvorhersagen und Cache - Misses auf CPU - Ebene, sondern Schlösser und Interprozess- Kommunikation werden immer viel mehr Bedeutung , da wir multi- bewegen Prozess- und Multiprozessor-Architekturen. Dreppers Artikel kann wirklich helfen, viele dieser Probleme zu verstehen.
quelle
Als Faustregel gilt: 95% Ihres Codes werden 5% der Zeit ausgeführt. Es macht keinen Sinn, zu optimieren, bevor Sie Ihren Code profiliert / bewertet haben und sehen, welche 5% in 95% der Fälle ausgeführt werden.
Jeder Idiot kann Mikrooptimierungen durchführen und jeder anständige Compiler / Runtime wird dies für Sie tun.
Das Optimieren von gutem Code ist trivial. Das Schreiben von optimiertem Code und der Versuch, ihn danach wieder gut zu machen, ist bestenfalls mühsam und im schlimmsten Fall nicht nachhaltig.
Wenn Sie ernsthaft Wert auf Leistung legen, verwenden Sie PHP nicht für leistungskritischen Code. Finden Sie die Engpässe und schreiben Sie sie mit C-Erweiterungen neu. Selbst die Mikrooptimierung Ihres PHP-Codes über den Punkt der Verschleierung hinaus bringt Ihnen nicht annähernd so viel Geschwindigkeit.
Persönlich mochte ich die Mikrooptimierung sehr, als ich anfing zu programmieren. Weil es offensichtlich ist. Weil es dich schnell belohnt. Weil Sie keine wichtigen Entscheidungen treffen müssen. Es ist das perfekte Mittel zum Aufschieben. Damit können Sie den wirklich wichtigen Teilen der Softwareentwicklung entfliehen: dem Entwurf skalierbarer, flexibler, erweiterbarer und robuster Systeme.
quelle
Ich stimme Ihrem Vater zu: "Wenn ein Programmierer die Leistung in seinem Code selbst auf Mikroebene nicht berücksichtigt, sind sie keine guten Programmierer." Der Schlüssel ist, "Leistung zu betrachten". Das ist nicht gleichbedeutend mit "Mikrooptimierungen bei jedem Schritt durchführen".
Ich stimme den meisten anderen Kommentaren zu - was früher C-Programme schneller gemacht hat, ist heute vielleicht nicht mehr so -, aber es gibt noch andere ernste Dinge zu beachten: Soll ich C oder C ++ verwenden? Klassen mit einfachen überladenen Operatoren können die Leistung beeinträchtigen, wenn Sie sie häufig verwenden. Spielt das eine Rolle? Es hängt von Ihrer Anwendung ab, aber wenn Sie es nicht einmal berücksichtigen, sind Sie kein sehr guter Programmierer. Einige Leute mögen es für ungefähr 2 Millisekunden in Betracht ziehen und es ablehnen, aber ich denke, viel zu viele denken buchstäblich nicht einmal darüber nach.
Die Realität ist, dass mit der Optimierung Code schwerer zu lesen sein kann. Das Schreiben von Code dauert länger. Code wird irgendwo zwischen etwas schneller und einer Größenordnung schneller sein (das ist selten). Ihre Kunden werden den Unterschied wahrscheinlich nicht kennen.
Eine andere Realität ist, dass die Leute Code gerne wiederverwenden, und wo er landet, kann ganz anders sein als zu dem Zeitpunkt, als Sie ihn geschrieben haben. Plötzlich können sich die Leute interessieren.
Angenommen, Sie haben etwas wie Angry Birds auf einem PC oder für eine Spielekonsole geschrieben. Sie haben die Optimierung in Ihrem Physiksystem und Ihrem Grafiksystem außer Acht gelassen - denn heutzutage sind Doppelkerne mit 2,5 GHz im Grunde genommen das Minimum und Ihr Spiel funktioniert gut genug. Dann kommen Smartphones und Sie möchten es portieren. Oh verdammt, ein 600 MHz ARM- Kern?
Denken Sie an eine Website - etwas, das an einem Wochenende wie Hot or Not zusammengewürfelt wird . Sie verwenden eine beliebige Datenbank, schreiben alles im Hinblick auf eine schnelle Entwicklung und senden Ihren Freunden per E-Mail eine URL. Drei Monate später stirbt Ihr Server an Überlastung, und Sie können nichts tun, um die Größe zu erhöhen. Es passiert ständig. Die größten Websites haben Stromrechnungen, die in Hunderten von Kilowatt oder sogar Megawatt gemessen werden. Denken Sie darüber nach, es gibt Megawatt, die durch Codeoptimierung eingespart werden müssen.
Wie dein Vater sagte, musst du zumindest darüber nachdenken . Die meisten Leute wissen nicht einmal, wie viel Leistung auf dem Tisch ist, und beschönigen sie mit einem kurzen Spruch über "vorzeitige Optimierung" und "Tun Sie es nicht". Das sind keine guten Programmierer.
Dies ist keine populäre Meinung auf diesen Seiten. Tschüss Reputationspunkte ....
quelle
Nehmen wir zuerst Ihren Fall: PHP
Im Allgemeinen,
Ich würde "TOOOOO" nicht viel Zeit damit verbringen, meinen Code in einer dynamischen Sprache wie Python oder Ruby zu optimieren - denn sie sind NICHT für CPU-intensive Aufgaben beim Knacken von Zahlen konzipiert. Sie lösen verschiedene Problemklassen, bei denen es wichtiger ist, eine reale Situation auf eine aufwändige Art und Weise zu modellieren (die leicht zu lesen und zu pflegen ist) - was als Expressivität bezeichnet wird - als Geschwindigkeit. Wenn Geschwindigkeit das Hauptanliegen wäre, wären sie nicht in erster Linie dynamisch.
Bei kompilierten Programmen (C ++, Java) ist die Optimierung wichtiger. Aber auch hier müssen Sie sich zuerst die Art / Domäne / den Zweck des Programms ansehen, das Sie schreiben. Sie sollten auch die Zeit für die Mikrooptimierung sorgfältig mit den Vorteilen aus dieser Optimierung abwägen. Wenn Sie noch mehr Optimierung benötigen, können Sie auch überlegen, einen Schritt nach unten zu gehen - und diese Teile Ihres Codes in Assembler zu codieren.
Um Ihre ursprüngliche Frage zu beantworten: "Ist die Mikrooptimierung beim Codieren wichtig?" - Die Antwort ist - es kommt darauf an -
Die Mikrooptimierung (eigentlich die Codeoptimierung) ist nicht nur zeitaufwändig, sondern "verzerrt" auch die natürliche Lesbarkeit Ihres Codes und macht ihn wartungsintensiv. Betrachten Sie es immer als letzten Ausweg - versuchen Sie immer, die gesamte Anwendung zu optimieren, indem Sie eine bessere Hardware und Architektur verwenden, als einzelne Codedateien zu optimieren.
quelle
Es scheint viele Antworten zu geben, die besagen, dass es sich um Mikrooptimierung handelt
Aber ich weiß, dass es einige Optimierungen gibt, bei denen die Lesbarkeit nicht beeinträchtigt wird, und ich mache diese nur zum Spaß. Ich habe bei einigen meiner Schulaufgaben (die alle geschwindigkeitsabhängig waren) festgestellt, dass es immer gut ist, die Mikrooptimierung in Betracht zu ziehen, wenn ich bedingte Anweisungen schreibe wie:
ist immer schöner als
Es gibt einige Möglichkeiten, Ihren Code so zu "beschleunigen", und der Unterschied ist normalerweise vernachlässigbar (nicht immer), aber ich fühle mich besser, wenn ich ihn so schreibe.
Ich weiß nicht, ob jemand dies überhaupt als Optimierung ansieht, aber ich denke, ein Programmierer sollte diese Dinge kennen und berücksichtigen, wenn er seinen Code schreibt.
quelle
cheap() && expensive()
eine Optimierung ist, die dazuexpensive () && cheap()
einlädt, blindlings untereinander zu ersetzen, ohne Rücksicht auf die signifikante semantische Veränderung, die sie hervorruft (in Sprachen, in denen&&
der Kurzschlussoperator verwendet wird).if (x<100 && isPrime(x))
, nur um es klarer zu machen.Zu Beginn meiner Karriere führten pauschale Aussagen wie "Nicht mikrooptimieren" zu viel Verwirrung. Alles ist umständlich; Daher sagen die Leute eher "Best Practice" als "Do This".
"Best Practice" ist unter allen Umständen die erste Wahl. Beispielsweise sollten LINQ und Entity Framework anstelle von Inline-SQL verwendet werden. In meiner Firma arbeiten wir mit SQL Server 2000 . SQL Server 2000 unterstützt kein Entity Framework. Best Practices erfordern:
Ich weiß aus Erfahrung, dass dies nicht passieren wird. So konnte ich aufhören, mich ohne Ende anstrengen oder nicht den Best Practices folgen.
Bei Entscheidungen, die sich auf das Gesamtergebnis auswirken, sind politische, technische und monetäre Erwägungen zu berücksichtigen. Denken Sie daran, wenn Sie eine Entscheidung treffen, und wählen Sie Ihre Schlachten mit Bedacht aus.
" Für alles gibt es eine Jahreszeit, eine Zeit für jede Aktivität unter dem Himmel. "
quelle
LINQ and Entity Framework should be used in lieu of inline SQL
- Bis Sie tatsächlich Inline-SQL benötigen, um etwas zu optimieren; Die von EF erzeugte SQL ist nicht immer optimal.Dies ist immer ein Kompromiss.
Erstens geht es in der Computerindustrie am Ende um Geld. Was Sie als Entwickler tun müssen, ist, einen Mehrwert für den Kunden zu generieren, damit Sie Geld verdienen (das ist eine Vereinfachung, aber der wichtigste Punkt ist hier).
Entwicklerzeit kostet Geld. Maschinenleistung kostet auch Geld. Normalerweise sind diese zweiten Kosten viel niedriger als die ersten. Es ist also von großer Bedeutung, über einen lesbaren und wartbaren Code zu verfügen, damit Entwickler die meiste Zeit damit verbringen können, Wert zu liefern.
In manchen Fällen kann die Mikrooptimierung wichtig sein. In der Regel handelt es sich jedoch um weniger lesbaren Code oder weniger erweiterbaren Code (dies ist nicht der Fall bei Ihrem verknüpften Beispiel, aber im Allgemeinen). Dies kostet irgendwann Entwicklerzeit. Diesmal ist es teurer als Maschinenleistung, aber es ist Verschwendung.
Zweitens kann die Mikrooptimierung in einem großen Projekt die Wartung und Weiterentwicklung immer schwieriger machen. Das Problem dabei ist, dass bei der Entwicklung möglicherweise keine andere Optimierung mehr möglich ist. Mit einer sich entwickelnden Anwendung erhalten Sie in der Regel eine Lösung, die langsamer ist als die, die Sie ohne diese Optimierungen gehabt hätten.
Drittens ist die Optimierung oftmals irrelevant, da die Komplexität des Algorithmus im Allgemeinen jede Mikrooptimierung überwindet, die Sie hätten durchführen können, wenn der Datensatz größer würde. Da die Mikrooptimierung die Wartung / Weiterentwicklung Ihres Codes erschwert, ist diese Optimierung möglicherweise schwieriger.
Manchmal liegt der Wert in dieser Optimierung (denken Sie an latenzkritische Programme wie in Videospielen oder dem Autopiloten eines Flugzeugs). Dies muss jedoch demonstriert werden. Normalerweise verbringt Ihr Programm die meiste Zeit in einem begrenzten Teil des Codes. Unabhängig davon, welche Mikrooptimierung Sie durchführen, werden Sie Ihre Programme niemals wertvoller beschleunigen, ohne den Engpass zu identifizieren und an diesem Teil zu arbeiten.
Wenn Sie Ihre Frage so stellen, wie Sie es getan haben, zeigt sich, dass Sie das Problem nicht mit einem tatsächlichen Programm verglichen haben. In diesem Fall hätten Sie den Trick machen und feststellen können, ob es schneller war oder nicht. Das haben Sie gefragt, bevor Sie ein Problem hatten. Hier liegt das Problem. Sie haben das Problem der Optimierung falsch behandelt.
Da Wartung und Weiterentwicklung in der Regel wertvoller sind als die Mikrooptimierung, sollten Sie zunächst die richtige Benutzeroberfläche auswählen. Wenn dann Teile Ihres Programms abstrakt genug für einander sind, können Sie eines mikrooptimieren, ohne das Ganze durcheinander zu bringen. Dies setzt voraus, dass Ihre Schnittstelle lange genug ausgeführt wird, um als vertrauenswürdig eingestuft zu werden.
quelle
Leistung ist ein Merkmal
Jeff Atwoods Artikel befasst sich hervorragend mit dem Aufbau einer leistungsstarken Website und der Wichtigkeit, dies zu tun ...
Konzentrieren Sie sich jedoch erst dann auf die Mikrooptimierung, wenn dies erforderlich ist. Sie können kostengünstigere Optimierungen durchführen. Konzentrieren Sie sich auf die Architektur, nicht auf den Code. Die meisten Websites, die ich gesehen habe und die nur langsam ausgeführt wurden, hatten Probleme auf hoher Ebene (unnötige Webserviceschicht, schlechtes Datenbankdesign, übermäßig komplizierte Architekturen), die nicht nur die Leistung beeinträchtigten, sondern tief verwurzelt und schwer zu beheben waren.
Wenn Sie eine Website erstellen, ist es weitaus wahrscheinlicher, dass Ihr clientseitiger Code und Ihre Datenbanklogik Leistungsprobleme verursachen als Ihr serverseitiger Code. Wenn Sie jedoch Leistungsprobleme haben, können Sie Ihren Code noch besser profilieren und frühzeitig finden.
quelle
Entwicklerzeit kostet mehr als Computerzeit. Das ist normalerweise das, was Sie optimieren möchten. Aber:
select (select count(*) from foo) >= 1
ist nicht das Gleiche wieselect exists(select 1 from foo)
.quelle
Was möchten Sie optimieren?
"Optimieren" bedeutet nicht immer, dass der Code so schnell wie möglich ausgeführt wird. Es gibt Zeiten, in denen es wichtig ist, den absolut schnellsten Weg zu finden, um etwas zu tun, aber das ist in den meisten Codes nicht so üblich. Wenn Benutzer den Unterschied zwischen 50 und 100 Mikrosekunden nicht bemerken, gibt es praktisch keinen Unterschied zwischen den beiden im Code, der nur gelegentlich ausgeführt wird. Hier ist ein Beispiel:
Wenn Sie die Anzeige der Länge der Benutzereingaben und die Zeitdauer, die eine der beiden Routinen benötigt, um diese Länge zu ermitteln, ständig aktualisieren müssen, ist die Zeit zwischen zwei aufeinander folgenden Tastenanschlägen sehr viel kürzer. Dabei spielt es keine Rolle, welche Routine verwendet wird Sie verwenden. Wenn Sie andererseits die Länge von einer Milliarde Zeichenfolgen bestimmen müssen, sollten Sie die Leistungsunterschiede zwischen den verschiedenen Routinen genau beachten. Im ersten Fall möchten Sie möglicherweise Code schreiben, der einfach zu verstehen und zu überprüfen ist. Im zweiten Fall sind Sie möglicherweise bereit, Lesbarkeit gegen Geschwindigkeit zu tauschen.
In jedem Fall sollten Sie, wenn Sie Ihren Code optimieren möchten, vor und nach jeder Änderung ein Profil für Ihren Code erstellen. Programme sind heutzutage so kompliziert, dass es oft schwierig ist zu sagen, wo die Engpässe liegen. Mithilfe der Profilerstellung können Sie den richtigen Code optimieren und anschließend zeigen, dass die von Ihnen vorgenommenen Optimierungen wirklich erfolgreich waren.
Sie haben nicht gesagt, wann Ihr Vater in den Ruhestand ging oder welche Art von Programmierung er durchführte, aber seine Reaktion ist nicht überraschend. In der Vergangenheit waren Speicher, sekundärer Speicher und Rechenzeit alle teuer und manchmal sehr teuer. Heutzutage sind all diese Dinge im Vergleich zur Programmiererzeit sehr billig geworden . Gleichzeitig sind Prozessoren und Compiler in der Lage, Code so zu optimieren, wie es Programmierer niemals schaffen würden. Die Zeiten, in denen Programmierer mit kleinen Tricks ein paar Maschinenanweisungen hier und da bumsen, sind meist vorbei.
quelle
Es ist nicht wichtig, beim Schreiben des Codes eine Mikrooptimierung vorzunehmen. Die Optimierung sollte mithilfe eines Profilers erfolgen, der den Code dort optimiert, wo er wichtig ist.
JEDOCH , ein Programmierer sollte versuchen zu tun offensichtlich dumme Dinge zu vermeiden , während Sie den Code zu schreiben.
Führen Sie zum Beispiel keine teuren Wiederholungsoperationen in einer Schleife durch. Speichern Sie den Wert in einer Variablen außerhalb der Schleife und verwenden Sie diese. Führen Sie in einer häufig aufgerufenen Funktion keine Dinge wie Zeichenfolgenvergleiche oder reguläre Ausdrücke immer wieder durch, wenn Sie eine Ebene höher gehen, den Vergleich durchführen und ihn in eine Ganzzahl, eine Funktionsreferenz oder eine abgeleitete Klasse umwandeln können.
Diese Dinge sind für einen erfahrenen Programmierer leicht zu merken und verbessern fast immer die Codequalität.
quelle
Denken Sie bei der Entscheidung, was optimiert werden soll, immer an Amdahls Gesetz . Siehe den Link für genaue Mathematik; Die markige Aussage, an die man sich erinnern sollte, ist:
Aus diesem Grund sagen die Leute immer, es lohnt sich nicht, Teile Ihres Programms zu optimieren, die nicht mehr als ein paar Prozent der Gesamtlaufzeit beanspruchen. Dies ist jedoch nur ein Sonderfall eines allgemeineren Prinzips. Amdahls Gesetz besagt, dass Sie jedes Teil um durchschnittlich 50% beschleunigen müssen, wenn das gesamte Programm doppelt so schnell ausgeführt werden soll . Wenn Sie zwanzig Gigabyte Daten verarbeiten müssen, gibt es nur zwei Möglichkeiten, um diese schneller zu machen als die Zeit, die zum Lesen von zwanzig Gigabyte von der Festplatte benötigt wird: eine schnellere Festplatte beschaffen oder die Daten verkleinern.
Was sagt Amdahls Gesetz über Mikrooptimierungen? Es sagt, dass sie es vielleicht wert sind, wenn sie sich auf der ganzen Linie bewerben. Wenn Sie die Laufzeit aller Funktionen in Ihrem Programm um ein Prozent verkürzen können, herzlichen Glückwunsch! Sie haben das Programm um ein Prozent beschleunigt. War es das wert? Nun, als Compiler-Typ würde ich mich freuen, eine Optimierung zu finden, die dies ermöglicht, aber wenn Sie es von Hand tun, würde ich sagen, suchen Sie nach etwas Größerem.
quelle
Es hängt davon ab, in welchem Entwicklungsstadium Sie sich befinden, wenn Sie anfangen, etwas zu schreiben. Mikrooptimierungen sollten keine Rolle spielen, da Sie durch die Verwendung guter Algorithmen mehr Leistungsgewinne erzielen als durch die Verwendung von Mikrooptimierungen. Überlegen Sie auch, was Sie entwickeln, da zeitkritische Anwendungen von Überlegungen zur Mikrooptimierung mehr profitieren als generische Geschäftsanwendungen.
Wenn Sie Software testen und erweitern, werden Sie wahrscheinlich durch Mikrooptimierungen verletzt, da sie das Lesen von Code erschweren und sogar ihre eigenen Fehler einführen, die behoben werden müssen, zusammen mit allem anderen, das behoben werden muss.
Wenn Sie tatsächlich Beschwerden von Benutzern über langsamen Code erhalten, sind diese möglicherweise eine Überlegung wert, aber nur, wenn alles andere behoben wurde, nämlich:
Wenn alle diese Fragen beantwortet wurden und Sie immer noch Leistungsprobleme haben, ist es möglicherweise an der Zeit, mit der Verwendung von Mikrooptimierungen im Code zu beginnen. Es besteht jedoch die Möglichkeit, dass andere Änderungen (z. B. besserer Code, besserer Algorithmus usw.) Sie in Mitleidenschaft ziehen Dies ist eher ein Leistungsgewinn als eine Mikrooptimierung.
quelle
Die Ausführungsgeschwindigkeit ist einer von vielen Faktoren, die zur Qualität eines Programms beitragen. Oft steht die Geschwindigkeit in umgekehrter Beziehung zur Lesbarkeit / Wartbarkeit. In fast allen Fällen muss der Code für den Menschen lesbar sein, damit der Code beibehalten werden kann. Die Lesbarkeit kann nur dann beeinträchtigt werden, wenn Geschwindigkeit eine wesentliche Voraussetzung ist. Die Forderung, Code schneller zu machen, als es die vollständige Lesbarkeit / Wartbarkeit zulässt, ist kaum anwendbar, aber es gibt bestimmte Fälle, in denen dies der Fall ist. Das Wichtigste, an das Sie sich erinnern sollten, ist, dass mikrooptimierter Code häufig Hacky-Code ist. Wenn also nicht irgendwo eine definierte Anforderung vorliegt, ist dies fast immer der falsche Weg, um das Problem zu lösen. Beispielsweise wird der Benutzer den Unterschied zwischen einer Ausführungszeit von 0,5 Sekunden und einer Ausführungszeit von 1 Sekunde bei CRUD-Operationen so gut wie nie bemerken. Sie müssen also nicht in ein Assembly-Interop-Hackfest gehen, um diese 0,5 Sekunden zu erreichen. Ja, ich könnte mit einem Hubschrauber zur Arbeit fliegen und es wäre zehnmal so schnell, aber ich nicht wegen des Preises und der Tatsache, dass Hubschrauber viel schwieriger zu fliegen ist.Wenn Sie Code unnötig mikrooptimieren, ist dies genau das, was Sie tun: Hinzufügen unnötiger Komplexität und Kosten, um ein überflüssiges Ziel zu erreichen.
quelle
Mikrooptimierung ist wichtig, wenn Sie eine Einschränkung treffen. Das, was Sie interessiert, ist möglicherweise Speicher, Durchsatz, Latenz oder Stromverbrauch. Beachten Sie, dass dies Merkmale auf Systemebene sind. Sie müssen (und können) nicht jede Funktion in jeder Hinsicht optimieren.
Eingebettete Systeme benötigen mit größerer Wahrscheinlichkeit eine Mikrooptimierung, da Einschränkungen leichter getroffen werden. Aber selbst dort bringt Sie die Mikrooptimierung nur so weit. Sie können Ihren Weg aus einem schlechten Design nicht mikrooptimieren. Der Punkt über gutes Design in einem System ist, dass Sie über das System als Ganzes nachdenken können. Komponenten, die einer Mikrooptimierung bedürfen, sollten sauber freigelegt und so optimiert werden, dass das Design des Systems nicht beeinträchtigt wird.
Beachten Sie, dass kleine "eingebettete" Systeme heutzutage den Vaxen oder PDP-11 von früher ziemlich nahe kommen können , sodass diese Probleme früher häufiger auftraten. Auf einem modernen Allzwecksystem, das moderne allgemeine kommerzielle Datenverarbeitung ausführt, ist eine Mikrooptimierung selten. Dies ist wahrscheinlich ein Grund, warum Ihr Vater die Position einnimmt, die er einnimmt.
Es spielt jedoch keine Rolle, ob Sie es mit Nanosekunden, Millisekunden, Sekunden oder Stunden zu tun haben. Die Probleme sind die gleichen. Sie müssen im Zusammenhang mit dem System und dem, was Sie erreichen möchten, bewertet werden.
Dies ist ein Beispiel aus einer kürzlich gestellten Frage zu Stack Overflow für einen Fall, in dem eine Mikrooptimierung erforderlich war: Open-Source-Videocodierer für ein eingebettetes System .
quelle
Das größte Problem bei der Mikrooptimierung ist, dass Sie einen Code schreiben müssen, der schwieriger zu warten ist.
Ein weiteres Problem ist, dass abhängig von der Computerkonfiguration Ihre Mikrooptimierung manchmal die schlechteste Leistung aufweist als ohne die "Optimierung".
Wenn Sie viele Mikrooptimierungen vornehmen, benötigen Sie viel Zeit, um gegen etwas anzukämpfen, das nicht wirklich wichtig ist.
Ein besserer Ansatz besteht darin, einen saubereren Code zu erstellen, der einfacher zu warten ist. Wenn Sie Leistungsprobleme haben, führen Sie ein Profil aus, um herauszufinden, was Ihren Code wirklich langsam macht. Und wenn Sie genau wissen, was wirklich schlecht ist, können Sie das Problem beheben.
Ich sage nicht, dass Mikrooptimierungen keine Entschuldigung dafür sind, dummen Code zu schreiben.
quelle
Wenn Sie sich Gedanken über Millisekunden machen, sollten Sie PHP aufgeben und stattdessen C oder Assembly verwenden. Nicht, dass ich das tun möchte, es macht einfach keinen Sinn, solche Zahlen zu diskutieren und eine Skriptsprache zu verwenden. Iteriert Ihr Code mit diesem Befehl sowieso so oft?
Die Umweltfaktoren stehen hier außer Frage, diese Server sind sowieso rund um die Uhr in Betrieb und wenn sie tatsächlich etwas verarbeiten, ist es nur wichtig, wenn es sich wirklich um eine Aufgabe handelt, die sehr lange ausgeführt wird.
Höchstwahrscheinlich wird das Licht in Ihrem Büro und die Energie, die unsere Computer verbraucht haben, während wir alle Fragen und Antworten getippt haben, viel mehr Energie verbrauchen, als jede Art von Mikrooptimierung, die Sie vernünftigerweise auf Ihre Anwendungen anwenden können, jemals einsparen wird.
quelle
Sie sollten den besten, einfachen Algorithmus für die Aufgabe auswählen. Der Grund, warum es einfach sein muss, ist, den Code lesbar zu halten. Der Grund, warum es das Beste sein muss, besteht darin, zu vermeiden, mit schlechten Laufzeitmerkmalen zu beginnen. Wählen Sie BubbleSort nicht blind, wenn Sie wissen, dass Sie große Datenmengen haben werden. Es ist jedoch in Ordnung für die gelegentliche Art von 10 Elementen.
DANN können Sie mit der Optimierung beginnen (was normalerweise die Kosten für die Lesbarkeit sind), wenn die Profiling-Zahlen belegen, dass Ihre Wahl des besten einfachen Algorithmus nicht gut genug war.
quelle
start out with bad runtime characteristic
Sie nicht absichtlich mit einem schlechten Laufzeitverhalten.Ich habe es schon einmal gesagt, und ich sage es hier: "Vorzeitige Optimierung ist die Wurzel allen Übels" . Dies sollte eine der Regeln sein, die den Programmierer in den Mittelpunkt stellen.
Code kann bis zu einem gewissen Punkt immer schneller sein als es derzeit ist. Wenn Sie die Baugruppe nicht mit einem bestimmten Chip von Hand verpacken, kann durch Optimierung immer etwas erreicht werden. Wenn Sie jedoch nicht für alles, was Sie tun, von Hand verpacken möchten, muss es ein quantitatives Ziel geben, bei dem Sie nach dem Erreichen des Ziels "das ist genug" sagen und die Optimierung beenden, auch wenn Sie immer noch einen krassen Leistungssauger anstarren dir ins gesicht.
Schöner, eleganter, extrem performanter Code ist nutzlos, wenn er nicht funktioniert (und mit "funktionieren" meine ich die erwartete Ausgabe bei allen erwarteten Eingaben). Daher sollte das Produzieren von Code, der funktioniert, IMMER die erste Priorität sein. Nachdem es funktioniert, bewerten Sie die Leistung, und wenn es Ihnen fehlt, suchen Sie nach Möglichkeiten, die Leistung zu verbessern, bis zu dem Punkt, an dem es gut genug ist.
Es gibt einige Dinge, die Sie im Vorfeld entscheiden müssen, um die Leistung zu beeinträchtigen. Grundlegende Entscheidungen wie die Sprache / Laufzeit, mit der Sie diese Lösung implementieren. Viele davon wirken sich um ein Vielfaches auf die Leistung aus, als wenn eine Methode gegen eine andere aufgerufen wird. Ehrlich gesagt ist PHP als Skriptsprache bereits ein Leistungstreffer, aber da in C / C ++ nur sehr wenige Skriptseiten von Grund auf erstellt werden, ist es mit anderen Technologien vergleichbar, aus denen Sie wahrscheinlich auswählen würden (Java-Servlets, ASP.NET) , usw).
Danach ist die E / A-Nachrichtengröße Ihr nächster Leistungskiller. Durch die Optimierung des Lese- und Schreibvorgangs auf Festplatte, seriellen Anschlüssen, Netzwerk-Pipes usw. wird die Laufzeit des Programms in der Regel um viele Größenordnungen verbessert, selbst wenn die Algorithmen für die E / A-Vorgänge effizient waren. Reduzieren Sie danach die Big-O-Komplexität des Algorithmus selbst, und wenn Sie dies unbedingt tun müssen, können Sie eine "Mikrooptimierung" durchführen, indem Sie kostengünstigere Methodenaufrufe auswählen und andere esoterische Entscheidungen auf niedriger Ebene treffen.
quelle
Sie erwähnen, dass Ihr Vater ein pensionierter Programmierer ist. Programmierer, die in der Mainframe-Welt arbeiteten, mussten sich sehr um die Leistung sorgen. Ich kann mich erinnern, eine US Navy-Aktivität untersucht zu haben, bei der der Mainframe auf 64 KB Arbeitsspeicher pro Benutzer beschränkt war. In dieser Programmierwelt muss man jedes noch so kleine Stück herausfinden.
Die Dinge sind jetzt völlig anders und die meisten Programmierer müssen sich nicht mehr so sehr um Mikrooptimierungen kümmern. Programmierer für eingebettete Systeme tun dies jedoch immer noch, und Datenbankmitarbeiter müssen immer noch optimierten Code verwenden.
quelle
Code sollte so geschrieben werden, dass absolut klar ist, was er tut. Dann, wenn und nur wenn es zu langsam ist, gehen Sie zurück und beschleunigen Sie es. Code kann immer geändert werden, um später schneller zu sein, wenn er verstanden werden kann - aber viel Glück beim Ändern, um klar zu sein, ob er schnell ist.
quelle
Es ist wichtig, wenn:
1) Jemandes Leben hängt von Ihrem Code ab. Eine Funktion, deren Ausführung im Pulsmesser einer Person 25 ms dauert, ist wahrscheinlich eine schlechte Idee.
Ich persönlich verfolge einen zweigleisigen Ansatz - es gibt Mikrooptimierungen, die die Lesbarkeit nicht beeinträchtigen. Natürlich möchten Sie diese verwenden. Wenn sich dies jedoch auf die Lesbarkeit auswirkt, halten Sie inne - Sie werden nicht viel davon profitieren und es könnte auf lange Sicht sogar länger dauern, bis Sie das Debuggen abgeschlossen haben.
quelle
Nein, da es Plattformen wie JVM und .NET gibt, auf denen Code für eine virtuelle Maschine geschrieben ist, und der Versuch, die Ausführung zu optimieren, möglicherweise nicht so gut funktioniert, wie es auf dem Desktop eines Entwicklers auf einem Server erforderlich ist. Schauen Sie sich an, wie weit einige dieser Teile der High-Level-Software von der Hardware entfernt sind. In Anbetracht der Vielfalt der Hardware ist zu bedenken, wie realistisch es ist, Code für bestimmte Chips wie eine CPU oder eine GPU zu optimieren, wenn ein neues Modell wahrscheinlich in weniger als einem Jahr herauskommt.
Eine weitere zu berücksichtigende Frage ist die Leistung, gemessen an welcher Metrik: Ausführungsgeschwindigkeit, bei der Ausführung verwendeter Speicher, Geschwindigkeit der Entwicklung neuer Features, Größe der Codebasis auf einem Server in kompilierten oder dekompilierten Formen, Skalierbarkeit, Wartbarkeit usw .? Wenn man es allgemein nimmt, wird die Frage trivial, aber ich bin mir nicht sicher, wie allgemein Sie die Leistung als wirklich ansehen wollten, das kann fast alles sein, solange es in irgendeiner Weise gemessen werden kann.
Einige Mikrooptimierungen funktionieren möglicherweise und einige funktionieren möglicherweise nicht. Hier kann man sich fragen, wie lohnend es ist, solche Arbeiten im Vergleich zu anderen Arbeiten durchzuführen, die als viel prioritärer angesehen werden, wie beispielsweise neue Funktionen oder das Beheben von Fehlern. Die andere Frage wäre, ob ein Upgrade der Hardware oder Software möglicherweise auch einige dieser Optimierungen beeinträchtigt.
quelle
Ich denke, dass es einen großen Unterschied zwischen guter Programmierung und Mikrooptimierung gibt.
Wenn es zwei Möglichkeiten gibt, die gleiche Aufgabe auszuführen, wobei eine schneller als die andere ist und beide die gleiche Lesbarkeit aufweisen, sollten Sie die schnellere verwenden. Immer. Und das ist eine gute Programmierung. Es gibt keinen Grund, keinen besseren Algorithmus zu verwenden, um ein Problem zu lösen. Und selbst das Dokumentieren ist ganz einfach: Geben Sie den Namen des Algorithmus an, und jeder kann ihn googeln und weitere Informationen darüber finden, wie er funktioniert.
Und gute Algorithmen sind bereits optimiert. Sie werden schnell sein. Sie werden klein sein. Sie werden den minimal erforderlichen Speicher verwenden.
Selbst wenn Ihr Programm diese Leistung noch nicht aufweist, können Sie eine Mikrooptimierung in Betracht ziehen. Und Sie müssen die Sprache wirklich kennen, um eine Mikrooptimierung durchführen zu können.
Und es gibt immer Platz, um mehr Geld für Hardware auszugeben. Hardware ist billig, Programmierer sind teuer . Verbringen Sie nicht zu viel Zeit / Geld, indem Sie optimieren, wann Sie nur Hardware kaufen können.
quelle
IMHO- Code-Lesbarkeit ist wichtiger als Mikrooptimierung, da sich Mikrooptimierung in den meisten Fällen nicht lohnt.
Artikel über unsinnige Mikrooptimierungen :
In den meisten Fällen spart die Mikrooptimierung eine Operation unter Millionen, verschlechtert jedoch die Lesbarkeit.
quelle
Andere Antworten stimmen auf das Geld. Aber ich werde einen weiteren Punkt hinzufügen, an dem man unterscheiden muss, was vorzeitige Optimierung / Mikrooptimierung ist, und Performant-Code schreiben muss, der ein Verständnis des Verhaltens der Sprache / Framework-Konstrukte widerspiegelt (Entschuldigung, für das letzte Wort konnte kein Wort gefunden werden). . Der letzte ist eine gute Codierungspraxis und sollte im Allgemeinen durchgeführt werden!
Ich werde erklären. Eine schlechte Optimierung (vorzeitige Lese- / Mikrooptimierung) liegt nicht vor, wenn Sie Codeabschnitte ohne Profilerstellung optimieren, um festzustellen, ob es sich tatsächlich um Engpässe handelt. Es ist, wenn Sie basierend auf Ihren Annahmen, Hörsagen und undokumentierten Verhaltensweisen optimieren. Wenn es dokumentiert ist und etwas effizienter / logischer macht, wie klein es auch sein mag , nenne ich es gute Optimierung . Wie andere gesagt haben, haben beide Nachteile und fast keine Vorteile, wenn es darum geht, gute Geschäfte zu machen, aber ich mache immer noch das letztere, nicht das erstere, wenn es die Lesbarkeit nicht völlig zunichte macht. Ja, Lesbarkeit / Wartbarkeit ist von größter Bedeutung und es geht darum, wo Sie die Grenze ziehen.
Ich werde die von anderen hier gemachten Punkte als die Sinnlosigkeit von sowohl guten als auch schlechten Optimierungen wiederholen:
Ihre Abhängigkeiten von einem bestimmten Problem können sich ändern, und jeder Zeitaufwand für die Optimierung, bevor der logische Abschnitt Ihrer Anwendung abgeschlossen ist, ist Zeitverschwendung. Ich meine, relativ früh zu optimieren. Heute haben Sie eine
List<T>
und zu dem Zeitpunkt, an dem Ihre App ausgeliefert wurde, mussten Sie diese ändern.LinkedList<T>
Jetzt war das Benchmarking eine Verschwendung von Zeit und Mühe.Der eigentliche Engpass in Ihrer Anwendung (als messbarer Unterschied zu lesen) könnte meistens 5% Ihres Codes betragen (meistens die SQL-Codes), und die Optimierung der anderen 95% bringt Ihren Kunden keinen Nutzen.
Normalerweise bedeutet "technisch" besserer Code mehr Ausführlichkeit, was wiederum mehr fehleranfälligen Code bedeutet, was wiederum eine schwierigere Wartbarkeit und mehr Zeitaufwand bedeutet, was wiederum bedeutet, dass Sie weniger Geld verdienen.
Der CO2-Fußabdruck, den Sie für die ganze Welt durch einen Leistungszuwachs von 1% einsparen, wird leicht durch Treibhausgase in den Schatten gestellt, die Ihr Team beim Debuggen und Verwalten dieses Codes ausstoßen muss.
Die Nachteile einer schlechten Optimierung sind insbesondere:
Es gibt Ihnen nicht oft die Leistung, die Sie erwarten. Siehe diese Frage zu SO, wo Optimierungen fehlgeschlagen sind . In der Tat kann es nachteilige Auswirkungen haben. Das ist das Problem mit undokumentiertem Verhalten.
Die meisten modernen Compiler erledigen das sowieso für Sie.
Ich gebe einige Beispiele für schlechte und gute Optimierung:
Das Schlechte -
Verwendung von kleineren Integer-Typen anstelle von
Int32
.++i
verwendet statti++
for
stattforeach
(das Schlimmste, das ich gesehen habe, besiegt die Logik total)Ausgeschlossene Variablen vermeiden
Verwenden von
char
anstelle von String während der String-Verkettung, wie:Das Gute (aus der .NET-Welt. Sollte selbsterklärend sein) -
Doppelte Suche
Anstatt von
Lade sie alle
Anstatt von
Zweistufiges Casting:
Anstatt von
Wenn die Reihenfolge keine Rolle spielt
Anstatt von
Boxen
Anstatt von
Wenn Sie mich fragen, ob diese einen spürbaren Leistungsvorteil bringen, würde ich nein sagen. Aber ich würde vorschlagen, dass man sie verwenden sollte, da dies auf einem Verständnis des Verhaltens dieser Konstrukte beruht. Warum zwei Anrufe tätigen, wenn Sie nur einen tätigen können? Philosophisch gesehen ist es eine gute Codierungspraxis. Und 1 & 3 sind streng genommen auch etwas weniger lesbar, aber übertrumpfen sie die Lesbarkeit? Nein, nicht viel, also benutze ich. Das ist der Schlüssel - ein anständiges Verhältnis von Leistung zu Lesbarkeit aufrechtzuerhalten. Und wenn es das ist, geht es darum, wo Sie die Grenze ziehen.
quelle
"Wert es" braucht Kontext, wie viel einfacher es ist, zu schreiben und zu lesen und zu pflegen, im Vergleich dazu, wie viel schneller es dem Benutzer etwas deutlich reaktionsfähiger macht , interaktiv, und weniger Zeit für das Warten benötigt.
Ein paar Pfennige zu sparen, um eine Dose Soda zu kaufen, nützt mir nicht viel, wenn ich eine Strecke zurücklegen muss, um diese Pfennige zu sparen, zumal ich heutzutage selten Soda trinke. Ein paar Cent pro Dose bei einem Einkauf von einer Million Dosen Limonaden zu sparen, könnte ein riesiges Geschäft sein.
In der Zwischenzeit spart man ein paar Cent, wenn zwei Leute direkt neben mir sind und einer genau dasselbe für ein paar Cent billiger anbietet und der andere nicht, und ich wähle den teureren, weil mir der Hut besser gefällt, wie ein dummer Fall der Pessimisierung.
Was ich oft als "Mikrooptimierungen" bezeichne, scheint merkwürdigerweise frei von Messungen, Kontext und Benutzerdiskussion zu sein, wenn es absolut alle drei gibt, die solche Optimierungen in Betracht ziehen, wenn sie nicht einfach anzuwenden sind. Für mich bezieht sich eine richtige Mikrooptimierung heutzutage auf Dinge wie Speicherlayouts und Zugriffsmuster, und obwohl sie im Fokus "Mikro" zu sein scheinen, sind sie in ihrer Wirkung nicht Mikro.
Es ist mir vor nicht allzu langer Zeit gelungen, eine Operation von 24 Sekunden auf 25 Millisekunden (etwa 960-mal schneller) mit identischen Ausgaben (gesichert durch automatisierte Tests) zu reduzieren, ohne die algorithmische Komplexität für die volumetrische Wärmediffusionshautbildung zu ändern "Mikrooptimierungen" (die größten resultierten aus einer Änderung des Speicherlayouts, die auf ungefähr 2 Sekunden zurückging, der Rest waren Dinge wie SIMD und die weitere Analyse von Cache-Fehlern in VTune und eine weitere Neuordnung des Speicherlayouts).
Wolfire erklärt die Technik hier und kämpfte mit der erforderlichen Zeit: http://blog.wolfire.com/2009/11/volumetric-heat-diffusion-skinning/
Meine Implementierung hat es geschafft, dies in Millisekunden zu tun, während er sich bemühte, es auf weniger als eine Minute zu reduzieren:
Nachdem ich es von 24 Sekunden auf 25 Millisekunden "mikrooptimiert" hatte, war das ein Grundstein für den Workflow. Jetzt können Künstler ihre Rigs in Echtzeit mit über 30 FPS wechseln, ohne jedes Mal 24 Sekunden warten zu müssen, wenn sie kleine Änderungen an ihrem Rig vornehmen. Und das hat tatsächlich das gesamte Design meiner Software verändert, da ich keine Fortschrittsanzeige und solche Dinge mehr benötigte. Es wurde einfach alles interaktiv. Das mag also eine "Mikrooptimierung" in dem Sinne sein, dass alle Verbesserungen ohne eine Verbesserung der algorithmischen Komplexität erfolgten, aber es war eine eher "Megaoptimierung" in der Wirkung, die einen ehemals schmerzhaften, nicht interaktiven Prozess ausmachte in eine interaktive Echtzeitumgebung, die die Arbeitsweise der Benutzer grundlegend verändert hat.
Messung, Benutzeranforderungen, Kontext
Ich mochte Roberts Kommentar hier wirklich und habe vielleicht nicht den Punkt gemacht, den ich wollte:
Dies ist, trotz der Arbeit in einem sehr leistungskritischen Bereich mit häufig Echtzeitanforderungen, das einzige Mal, dass ich eine Mikrooptimierung in Betracht ziehe, die es erforderlich macht, mir aus dem Weg zu gehen.
Und ich möchte nicht nur die Messungen betonen, sondern auch die benutzerseitige Seite. Ich bin insofern ein Kuriosum, als ich zuerst als Benutzer / Fan, dann als Entwickler zu meinem derzeitigen Fach (und früher zu Gamedev) kam. Daher war ich nie so begeistert von den üblichen Dingen, die Programmierer zum Lösen technischer Rätsel anregen. Ich fand sie eine Last, würde sie aber durch den Benutzer-End-Traum tragen, den ich mit anderen Benutzern teilte. Aber das hat mir geholfen, um sicherzustellen, dass ich, wenn ich etwas optimiere, einen echten Einfluss auf die Benutzer mit echten Vorteilen habe. Es ist mein Schutz vor zielloser Mikrooptimierung.
Das ist meiner Meinung nach genauso wichtig wie der Profiler, weil ich Kollegen hatte, die Dinge wie die mikrooptimierte Unterteilung eines Würfels in eine Milliarde Facetten taten, um sich nur an realen Produktionsmodellen wie Charakteren und Fahrzeugen zu verschlucken. Ihr Ergebnis war in gewissem Sinne beeindruckend, aber für die tatsächlichen Benutzer nahezu nutzlos, da sie Profile erstellten und Fälle maßen und vergleichten, die nicht mit tatsächlichen Anwendungsfällen übereinstimmten. Deshalb ist es so wichtig zu verstehen, worauf es den Benutzern ankommt, indem sie lernen, die Software wie eine zu denken und zu verwenden oder mit ihnen zusammenzuarbeiten (im Idealfall beides, aber zumindest mit ihnen zusammenzuarbeiten).
quelle
isset
vs.strlen
mehr miniscule scheint Fokus in Ohne Kontext und Maße. :-DIch werde es so ausdrücken - Mikrooptimierung ist ein Prozess der Optimierung von etwas, das überhaupt kein Engpass ist. Wenn Ihr Programm beispielsweise zwei Funktionen A und B aufruft und die Ausführung von A 100 Millisekunden dauert und B 2 Mikrosekunden dauert und Sie die Funktion B weiter optimieren. Das ist nicht nur unwichtig, das ist absolut falsch. Die Optimierungsfunktion B heißt jedoch Optimierung und nicht Mikrooptimierung. Die Wichtigkeit der Optimierung hängt davon ab. Angenommen, Sie haben nichts anderes zu tun und Ihr Programm ist fehlerfrei, dann ist es wichtig. Aber im Allgemeinen haben Sie Prioritäten. Angenommen, Sie müssen die Funktion C hinzufügen / schreiben. Wenn Sie der Meinung sind, dass Sie mit der Schreibfunktion C mehr Geld verdienen, als wenn Sie Ihr Programm ohne diese Funktionalität schneller machen, dann optimieren Sie es. Andernfalls verfolgen Sie die Funktionalität. Ebenfalls, Erfahrene Programmierer, die sich auf Leistung konzentrieren, verbringen nicht viel Zeit mit der Optimierung. Sie schreiben nur schnelle Programme. Zumindest wissen sie, welche Tools sie verwenden müssen und was sie tun müssen, um nicht jahrelang bedeutungslose (Lese-Mikro-) Optimierungen vorzunehmen.
quelle