Sollte ein Entwickler zuerst Lesbarkeit oder Leistung anstreben? [geschlossen]


82

Oft steht ein Entwickler vor der Wahl zwischen zwei Möglichkeiten, ein Problem zu lösen - einer, die idiomatisch und lesbar ist, und einer, die weniger intuitiv ist, aber möglicherweise eine bessere Leistung erbringt. In C-basierten Sprachen gibt es beispielsweise zwei Möglichkeiten, eine Zahl mit 2 zu multiplizieren:

int SimpleMultiplyBy2(int x)
{
    return x * 2; 
}

und

int FastMultiplyBy2(int x)
{
    return x << 1;
}

Die erste Version ist sowohl für technische als auch für nichttechnische Leser einfacher zu erlernen, die zweite jedoch möglicherweise besser, da die Bitverschiebung einfacher ist als die Multiplikation. (Nehmen wir zunächst an, dass der Optimierer des Compilers dies nicht erkennt und optimiert, obwohl dies ebenfalls eine Überlegung ist.)

Was wäre als Entwickler als erster Versuch besser?


Ein bisschen hart. Gute Frage zu einem Anliegen, das wir alle manchmal haben. +1
Inisheer

3
Dieses Beispiel ist offensichtlich erfunden und trivial. Mit einem fest codierten Multiplikator hätten Sie eigentlich keine Funktion.
JohnMcG

1
Der Punkt ist, ich sehe viele Fragen wie "Leistung <besser als <=?" Dies ist die falsche Frage - die richtige (erste) Frage ist, welche idiomatisch oder konventionell ist, und sich dann um die Leistung zu sorgen.
JohnMcG

1
Dies ist eine der besten Fragen, die ich zum Stackoverflow gelesen habe. Dies bringt die Funktionsweise von Computern auf den Punkt, nicht nur die Semantik der Sprache. +1
WolfmanDragon

2
@OutlawLemur Das ist mir bewusst. Einige Leute fragen jedoch, ob es besser wäre, beispielsweise Schleifen mit <oder <= zu konstruieren (wobei der Vergleichswert im letzteren Fall vorher erhöht wird).
JohnMcG

Antworten:


108

Du hast einen verpasst.

Erst Code für Korrektheit, dann für Klarheit (die beiden sind natürlich oft miteinander verbunden!). Schließlich und nur wenn Sie echte empirische Beweise haben, die Sie tatsächlich benötigen, können Sie sich mit der Optimierung befassen. Vorzeitige Optimierung ist wirklich böse. Die Optimierung kostet Sie fast immer Zeit, Klarheit und Wartbarkeit. Sie sollten besser sicher sein, dass Sie damit etwas kaufen, das sich lohnt.

Beachten Sie, dass gute Algorithmen fast immer die lokalisierte Abstimmung übertreffen. Es gibt keinen Grund, warum Sie keinen Code haben können, der korrekt, klar und schnell ist. Sie werden unangemessen viel Glück haben, wenn Sie sich auf "schnell" konzentrieren.


Dies ist bei weitem die beste Antwort hier. Optimieren Sie den Algorithmus, nicht den Code. Mit subtilen Änderungen kann ich ein jscript-Sieb von Erastosthenes dazu bringen, eine ansonsten identische C ++ - Version zu übertreffen. (Nicht das Sieb von Atkins, meine eigene Methode.)
Peter Wone

2
Schade, dass Sie keine Antworten bevorzugen können. :)
Sandor Davidhazi

59

IMO zuerst die offensichtlich lesbare Version, bis die Leistung gemessen wird und eine schnellere Version erforderlich ist.


Genau. Letztes Jahr habe ich neben der serverseitigen Java-Codebasis meines Unternehmens eine wichtige Komponente implementiert und mein Bestes getan, um sie lesbar zu machen. Später stellte sich heraus, dass es Leistungsprobleme gab, und das Design wurde grundlegend überarbeitet, was zu etwas führte, das in gewisser Weise etwas weniger lesbar ist.
Ryan Delucchi

46

Nimm es von Don Knuth

Vorzeitige Optimierung ist die Wurzel allen Übels (oder zumindest des größten Teils davon) in der Programmierung.


Das Zitat stammt nicht von Don selbst, sondern von Hoare. Don hat es gerade populär gemacht. Überprüfen Sie Wikipedia.
Kohlerm

1
Und es ist ein selektives Zitat einer Klausel aus einem ganzen Absatz, die einige sehr wichtige Qualifikationen enthält.
Marquis von Lorne

19

Lesbarkeit 100%

Wenn Ihr Compiler die Optimierung "x * 2" => "x << 1" nicht für Sie durchführen kann, holen Sie sich einen neuen Compiler!

Denken Sie auch daran, dass 99,9% der Zeit Ihres Programms damit verbracht wird, auf Benutzereingaben, Datenbankabfragen und Netzwerkantworten zu warten. Wenn Sie nicht die mehrfachen 20 Bajillionen Male machen, wird es nicht auffallen.


8

In Ihrem Beispiel generieren 99,9999% der Compiler den gleichen Code für beide Fälle. Dies veranschaulicht meine allgemeine Regel: Schreiben Sie zuerst auf Lesbarkeit und Wartbarkeit und optimieren Sie nur, wenn Sie dies benötigen.


C-Compiler werden für die beiden gezeigten Beispiele in einen anderen Assembler-Code kompiliert. Die erste erstellt eine Schleife, während die zweite eine Anweisung zum Verschieben nach links erstellt. Dies sollte für alle Compiler im C-Stil gelten, da ich nicht jeden getestet habe, kann ich dazu keine Zusagen machen.
WolfmanDragon

Für dieses spezielle Beispiel sicherlich. Es gibt viele Fälle, in denen dies nicht der Fall ist, daher ist die allgemeine Frage immer noch gut
Mark Baker,

@ WolfmanDragon, wovon zum Teufel redest du? Warum sollte "* 2" eine Schleife erzeugen? Wenn ich es mit "gcc -O2 -s" versuche, erhalte ich in beiden Fällen zusätzliche Anweisungen.
Paul Tomblin

1
Wenn Ihr Compiler in dieser Funktion eine Schleife erstellt, würde ich Ihnen empfehlen, einen anderen Compiler zu verwenden!
Martin Vilcans

8

Lesbarkeit sicher. Mach dir keine Sorgen über die Geschwindigkeit, es sei denn, jemand beschwert sich


8

Lesbarkeit.

Das Codieren für die Leistung hat seine eigenen Herausforderungen. Joseph M. Newcomer hat es gut gesagt

Optimierung ist nur dann wichtig, wenn es darauf ankommt. Wenn es darauf ankommt, ist es sehr wichtig, aber bis Sie wissen, dass es wichtig ist, verschwenden Sie nicht viel Zeit damit. Selbst wenn Sie wissen, dass es wichtig ist, müssen Sie wissen, wo es wichtig ist. Ohne Leistungsdaten wissen Sie nicht, was Sie optimieren sollen, und Sie werden wahrscheinlich das Falsche optimieren.

Das Ergebnis ist dunkel, schwer zu schreiben, schwer zu debuggen und schwer zu pflegender Code, der Ihr Problem nicht löst. Dies hat den doppelten Nachteil, dass (a) die Kosten für Softwareentwicklung und Softwarewartung steigen und (b) überhaupt keine Leistungseffekte auftreten.


5

Lesbarkeit. Die Zeit für die Optimierung ist, wenn Sie mit dem Betatest beginnen. Ansonsten weiß man nie wirklich, wofür man die Zeit verbringen muss.


5

Ich würde zuerst die Lesbarkeit anstreben . In Anbetracht der Tatsache, dass mit der Art von optimierten Sprachen und enorm geladenen Maschinen, die wir heutzutage haben, der größte Teil des Codes, den wir lesbar schreiben, eine anständige Leistung erbringt.

In einigen sehr seltenen Szenarien, in denen Sie ziemlich sicher sind, dass Sie einen Performance-Flaschenhals haben werden (möglicherweise aus schlechten Erfahrungen in der Vergangenheit), und Sie es geschafft haben, einen seltsamen Trick zu finden, der Ihnen einen enormen Leistungsvorteil verschafft, können Sie sich entscheiden Das. Sie sollten dieses Code-Snippet jedoch sehr gut kommentieren, um es besser lesbar zu machen.


4

Ein häufig übersehener Faktor in dieser Debatte ist die zusätzliche Zeit, die ein Programmierer benötigt, um weniger lesbaren Code zu navigieren, zu verstehen und zu ändern. Wenn man bedenkt, dass die Zeit eines Programmierers hundert Dollar pro Stunde oder mehr beträgt, sind dies sehr reale Kosten.
Jedem Leistungsgewinn werden diese direkten Mehrkosten in der Entwicklung entgegengewirkt.


4

Wenn Sie dort einen Kommentar mit einer Erklärung einfügen, wird er lesbar und schnell.

Es hängt wirklich von der Art des Projekts ab und davon, wie wichtig die Leistung ist. Wenn Sie ein 3D-Spiel erstellen, gibt es normalerweise viele gängige Optimierungen, die Sie auf dem Weg dorthin einbringen möchten, und es gibt keinen Grund, dies nicht zu tun (lassen Sie sich einfach nicht zu früh mitreißen). Aber wenn Sie etwas Kniffliges tun, kommentieren Sie es, damit jeder, der es betrachtet, weiß, wie und warum Sie knifflig sind.


3

Die Antwort hängt vom Kontext ab. Beispielsweise ist bei der Programmierung von Gerätetreibern oder der Spieleentwicklung die zweite Form eine akzeptable Redewendung. In Geschäftsanwendungen nicht so sehr.

Am besten schauen Sie sich im Code (oder in ähnlich erfolgreichen Anwendungen) um, um zu überprüfen, wie andere Entwickler dies tun.


3

mit << würde durch eine Mikrooptimierung. Also Hoares (nicht Knuts) Regel:

Vorzeitige Optimierung ist die Wurzel allen Übels.

gilt und Sie sollten zunächst nur die besser lesbare Version verwenden.

Dies ist die Regel, die meiner Meinung nach häufig als Ausrede für das Entwerfen von Software missbraucht wird, die niemals skaliert werden kann oder eine gute Leistung erbringt.


3

Beide. Ihr Code sollte beides ausgleichen. Lesbarkeit und Leistung. Weil das Ignorieren eines der beiden den ROI des Projekts beeinträchtigt, was letztendlich alles ist, was für Ihren Chef wichtig ist.

Eine schlechte Lesbarkeit führt zu einer verminderten Wartbarkeit, was dazu führt, dass mehr Ressourcen für die Wartung aufgewendet werden, was zu einem niedrigeren ROI führt.

Eine schlechte Leistung führt zu einer Verringerung der Investition und des Kundenstamms, was zu einem niedrigeren ROI führt.


2

Je größer die Codebasis ist, desto wichtiger ist die Lesbarkeit. Der Versuch, eine winzige Funktion zu verstehen, ist nicht so schlimm. (Zumal der Methodenname im Beispiel einen Hinweis gibt.) Nicht so toll für ein episches Stück Uber-Code, das vom Einzelgänger-Genie geschrieben wurde, das gerade mit dem Codieren aufgehört hat, weil er endlich die Komplexität seiner Fähigkeiten erkannt hat und es genau das ist, was er gerade ist schrieb für Sie und Sie werden es nie verstehen.


2

Wenn Sie sich Sorgen über die Lesbarkeit Ihres Codes machen, zögern Sie nicht, einen Kommentar hinzuzufügen, um sich daran zu erinnern, was und warum Sie dies tun.


1

Die Bitverschiebung gegenüber der Multiplikation ist eine triviale Optimierung, die so gut wie nichts gewinnt . Und wie bereits erwähnt, sollte Ihr Compiler dies für Sie tun. Davon abgesehen ist die Verstärkung ohnehin vernachlässigbar, ebenso wie die CPU, auf der dieser Befehl ausgeführt wird.

Wenn Sie jedoch ernsthafte Berechnungen durchführen müssen, benötigen Sie die richtigen Datenstrukturen. Wenn Ihr Problem jedoch komplex ist, ist es Teil der Lösung, dies herauszufinden. Betrachten Sie zur Veranschaulichung die Suche nach einer ID-Nummer in einem Array von 1000000 unsortierten Objekten. Überdenken Sie dann die Verwendung eines Binärbaums oder einer Hash-Map.

Optimierungen wie n << C sind jedoch normalerweise vernachlässigbar und können jederzeit geändert werden. Code lesbar zu machen ist nicht.


1

Dies hängt von der zu lösenden Aufgabe ab. Normalerweise ist die Lesbarkeit wichtiger, aber es gibt noch einige Aufgaben, wenn Sie zuerst an die Leistung denken sollten. Und Sie können nicht einfach einen Tag oder Zeit für die Profilerstellung und Optimierung aufwenden, nachdem alles perfekt funktioniert, da für die Optimierung selbst möglicherweise ein ausreichender Teil eines Codes von Grund auf neu geschrieben werden muss. Aber es ist heutzutage nicht üblich.


1

Sie sollten immer maximal optimieren, die Leistung zählt immer. Der Grund, warum wir heute Bloatware haben, ist, dass die meisten Programmierer nicht die Arbeit der Optimierung machen wollen.

Trotzdem können Sie jederzeit Kommentare dort einfügen, wo die Slick-Codierung geklärt werden muss.


Ich stimme in einem bestimmten Punkt zu. Ich denke nicht, dass Sie Mikrooptimierungen wie in der ursprünglichen Frage vornehmen sollten. Sie müssen Ihr System so gestalten, dass Sie die Ressourcen optimal nutzen. In diesem Bereich gibt es viel mehr Leistung zu erzielen.
Erik van Brakel

Wir haben heute Bloatware, aber ich beschuldige nicht die mangelnde Optimierung. Ich beschuldige das Überdesign, das Klopfen von Fliegen mit Panzerfäusten und den Bau von Ozeandampfern, wenn nur Ruderboote benötigt werden. Dann ist es natürlich schwerfällig.
Mike Dunlavey

Ich stimme Ihnen beiden darin zu, dass die Optimierung des Designs oberste Priorität hat. Ich würde auch sagen, dass dieselbe Einstellung auf alle Ebenen des Software-Engineering-Prozesses angewendet werden sollte. Wenn Sie sich nicht die Mühe machen, auf Codeebene zu optimieren, fehlt es Ihnen wahrscheinlich auch beim Design.
Lance Roberts

1

Es macht keinen Sinn zu optimieren, wenn Sie Ihre Engpässe nicht kennen. Möglicherweise haben Sie eine Funktion unglaublich effizient gemacht (normalerweise auf Kosten der Lesbarkeit bis zu einem gewissen Grad), nur um festzustellen, dass ein Teil des Codes kaum ausgeführt wird, oder Sie verbringen mehr Zeit damit, auf die Festplatte oder Datenbank zuzugreifen, als Sie jemals Twiddling-Bits sparen. Sie können also nicht mikrooptimieren, bis Sie etwas zu messen haben, und dann können Sie genauso gut mit der Lesbarkeit beginnen. Sie sollten jedoch beim Entwerfen der Gesamtarchitektur sowohl auf Geschwindigkeit als auch auf Verständlichkeit achten, da beide einen massiven Einfluss haben und schwer zu ändern sind (abhängig vom Codierungsstil und den Methoden).


1

Schätzungen zufolge entfallen etwa 70% der Softwarekosten auf die Wartung. Die Lesbarkeit erleichtert die Wartung eines Systems und senkt daher die Kosten der Software über die gesamte Lebensdauer.

Es gibt Fälle, in denen die Leistung wichtiger ist als die Lesbarkeit, obwohl es nur wenige gibt.

Bevor Sie die Lesbarkeit beeinträchtigen, denken Sie: "Bin ich (oder Ihr Unternehmen) bereit, mit den zusätzlichen Kosten umzugehen, die ich dem System dadurch hinzufüge?"


1

Ich arbeite nicht bei Google, also würde ich mich für die böse Option entscheiden. (Optimierung)

In Kapitel 6 von Jon Bentleys "Programming Pearls" beschreibt er, wie ein System durch Optimierung auf 6 verschiedenen Designebenen 400-mal schneller wurde. Ich glaube, dass moderne Implementierer, wenn sie sich nicht um die Leistung auf diesen 6 Designebenen kümmern, leicht 2-3 Größenordnungen langsamer in ihren Programmen verlangsamen können.


1

Wie fast jeder in seinen Antworten sagte, bevorzuge ich die Lesbarkeit . 99 von 100 Projekten, die ich durchführe, haben keine strengen Anforderungen an die Reaktionszeit, daher ist dies eine einfache Wahl.

Bevor Sie überhaupt mit dem Codieren beginnen, sollten Sie die Antwort bereits kennen. Einige Projekte haben bestimmte Leistungsanforderungen, z. B. "Aufgabe X muss in Y (Millisekunden) Sekunden ausgeführt werden können". Wenn dies der Fall ist, haben Sie ein Ziel, auf das Sie hinarbeiten müssen, und Sie wissen, wann Sie optimieren müssen oder nicht. (hoffentlich) wird dies in der Anforderungsphase Ihres Projekts festgelegt, nicht beim Schreiben des Codes.

Gute Lesbarkeit und die Möglichkeit zur späteren Optimierung sind das Ergebnis eines ordnungsgemäßen Software-Designs. Wenn Ihre Software ein solides Design aufweist, sollten Sie in der Lage sein, Teile Ihrer Software zu isolieren und bei Bedarf neu zu schreiben, ohne andere Teile des Systems zu beschädigen. Außerdem waren die meisten echten Optimierungsfälle, auf die ich gestoßen bin (einige echte Tricks auf niedriger Ebene wurden ignoriert, die zufällig sind), der Wechsel von einem Algorithmus zu einem anderen oder das Zwischenspeichern von Daten im Speicher anstelle von Festplatte / Netzwerk.


1

Lesbarkeit ist das ERSTE Ziel.

In den 1970er Jahren testete die Armee einige der damals "neuen" Techniken der Softwareentwicklung (Top-Down-Design, strukturierte Programmierung, Chefprogrammiererteams, um nur einige zu nennen), um festzustellen, welche davon einen statistisch signifikanten Unterschied machten.

Die einzige Technik, die einen statistisch signifikanten Unterschied in der Entwicklung ausmachte, war ...

HINZUFÜGEN VON LEEREN LINIEN zum Programmcode.

Die Verbesserung der Lesbarkeit in diesen vorstrukturierten, vorobjektorientierten Codes war die einzige Technik in diesen Studien, die die Produktivität verbesserte.

==============

Die Optimierung sollte nur dann erfolgen, wenn das gesamte Projekt einheitlich getestet und für die Instrumentierung bereit ist. Sie wissen nie, wo Sie den Code optimieren müssen.

In ihren wegweisenden Büchern Kernigan und Plauger in den späten 1970er Jahren zeigten SOFTWARE TOOLS (1976) und SOFTWARE TOOLS IN PASCAL (1981) Möglichkeiten, strukturierte Programme mit Top-Down-Design zu erstellen. Sie erstellten Textverarbeitungsprogramme: Editoren, Suchwerkzeuge, Code-Vorprozessoren.

Als die abgeschlossene Textformatierungsfunktion INSTRUMENTIERT wurde, stellten sie fest, dass der größte Teil der Verarbeitungszeit in drei Routinen für die Texteingabe und -ausgabe aufgewendet wurde (im Originalbuch nahmen die Io-Funktionen 89% der Zeit in Anspruch. Im Pascal-Buch waren diese Funktionen vorhanden verbraucht 55%!)

Sie konnten diese DREI Routinen optimieren und die Ergebnisse einer Leistungssteigerung mit angemessener, überschaubarer Entwicklungszeit und -kosten erzielen.


1

Lesbarkeit zuerst. Aber noch mehr als Lesbarkeit ist Einfachheit, insbesondere in Bezug auf die Datenstruktur.

Ich erinnere mich an einen Studenten, der ein Visionsanalyseprogramm durchführte und nicht verstehen konnte, warum es so langsam war. Er folgte lediglich einer guten Programmierpraxis - jedes Pixel war ein Objekt, und es funktionierte, indem Nachrichten an seine Nachbarn gesendet wurden ...

Schau dir das an


1

Wenn keine Lesbarkeit vorliegt, ist es sehr schwierig, die Leistung zu verbessern, wenn Sie sie wirklich benötigen.

Die Leistung sollte nur verbessert werden, wenn es sich um ein Problem in Ihrem Programm handelt. Es gibt viele Stellen, an denen ein Flaschenhals anstelle dieser Syntax vorhanden ist. Angenommen, Sie erzielen eine Verbesserung von 1 ns gegenüber einem <<, haben diese 10-minütige E / A-Zeit jedoch ignoriert.

In Bezug auf die Lesbarkeit sollte ein professioneller Programmierer in der Lage sein, Begriffe der Informatik zu lesen / verstehen. Zum Beispiel können wir eine Methoden-Enqueue benennen, anstatt putThisJobInWorkQueue zu sagen.


Ich stimme zu, aber ich denke, Sie haben ein schlechtes Beispiel. Als jemand, der nichts über Ihre Codebasis weiß, bedeutet Enqueue für mich weniger. Ich will nicht wissen wie, ich will was wissen. Das Beispiel, das Sie gegeben haben, sagt, was viel besser ist.
Shaun Sweet

0

Schreiben Sie zuerst, um die Lesbarkeit zu gewährleisten, aber erwarten Sie, dass die Leser Programmierer sind . Jeder Programmierer, der sein Geld wert ist, sollte den Unterschied zwischen einer Multiplikation und einer Bitverschiebung kennen oder in der Lage sein, den ternären Operator zu lesen, wo er angemessen verwendet wird, einen komplexen Algorithmus nachschlagen und verstehen können (Sie kommentieren Ihren Code richtig? ), etc.

Eine frühe Überoptimierung ist natürlich ziemlich schlecht, um Sie später in Schwierigkeiten zu bringen, wenn Sie eine Umgestaltung vornehmen müssen, aber das gilt nicht wirklich für die Optimierung einzelner Methoden, Codeblöcke oder Anweisungen.


0

Ich würde sagen, gehen Sie für Lesbarkeit.

Aber im gegebenen Beispiel denke ich, dass die zweite Version bereits lesbar genug ist, da der Name der Funktion genau angibt, was in der Funktion vor sich geht.

Wenn wir nur immer Funktionen hatten, die uns sagten, was sie tun ...


0

Wie viel kostet eine Stunde Prozessorzeit?

Wie viel kostet eine Stunde Programmiererzeit?


Wie viel kostet eine Stunde Endbenutzerzeit? Nun multiplizieren Sie das mit der Anzahl der Benutzer.
Gbjbaanb

gbjbaanb: Meine Gedanken genau. Andys Kommentar funktioniert nur für Dienste, die der Endbenutzer niemals sehen wird, und selbst dann ist es kaum ein guter Vergleich.
Erik van Brakel

0

IMHO haben beide Dinge nichts zu tun. Sie sollten sich zuerst für Code entscheiden, der funktioniert, da dies wichtiger ist als die Leistung oder die Lesbarkeit. In Bezug auf die Lesbarkeit: Ihr Code sollte auf jeden Fall immer lesbar sein.

Ich verstehe jedoch nicht, warum Code nicht lesbar ist und gleichzeitig eine gute Leistung bietet. In Ihrem Beispiel ist die zweite Version für mich genauso lesbar wie die erste. Was ist daran weniger lesbar? Wenn ein Programmierer nicht weiß, dass das Verschieben nach links das gleiche ist wie das Multiplizieren mit einer Zweierpotenz und das Verschieben nach rechts das gleiche wie das Teilen durch eine Zweierpotenz ... dann haben Sie viel grundlegendere Probleme als die allgemeine Lesbarkeit.

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.