Was ist die lächerlichste Pessimisierung, die Sie gesehen haben? [geschlossen]


145

Wir alle wissen, dass vorzeitige Optimierung die Wurzel allen Übels ist, weil sie zu unlesbarem / nicht wartbarem Code führt. Noch schlimmer ist die Pessimisierung, wenn jemand eine "Optimierung" implementiert, weil er glaubt , dass sie schneller sein wird, aber am Ende langsamer, fehlerhaft, nicht wartbar usw. Was ist das lächerlichste Beispiel dafür, das Sie gesehen haben ?


21
"Pessimisierung" ist ein großartiges Wort.
mqp

Nur für den Fall, dass Sie es nicht wussten, haben sie hier im neuesten Podcast über Ihren Thread gesprochen.
mmcdole

Antworten:


81

Bei einem alten Projekt haben wir einige (ansonsten ausgezeichnete) Programmierer für eingebettete Systeme geerbt, die über umfangreiche Erfahrung mit Z-8000 verfügten.

Unsere neue Umgebung war 32-Bit-Sparc Solaris.

Einer der Jungs hat alle Ints in Shorts geändert, um unseren Code zu beschleunigen, da das Abrufen von 16 Bit aus dem RAM schneller war als das Abrufen von 32 Bit.

Ich musste ein Demo-Programm schreiben, um zu zeigen, dass das Abrufen von 32-Bit-Werten auf einem 32-Bit-System schneller war als das Abrufen von 16-Bit-Werten, und erklären, dass die CPU zum Abrufen eines 16-Bit-Werts eine 32-Bit-Breite erstellen musste Speicherzugriff und dann Maskieren oder Verschieben der für den 16-Bit-Wert nicht benötigten Bits.


16
Hey, wo hast du deine Mathematik gelernt? 2 Befehle mit 1 Cache / RAM-Zugriff sind offensichtlich schneller als 1 Befehl mit 1 Cache / RAM-Zugriff!
Rasiermesser Sturm

2
@RazorStorm Auf späteren Computern, auf denen Bandbreite und Cache wertvoller sind, ist das Gegenteil der Fall. Die Bitmaske / Verschiebung ist billig, aber Sie möchten so viel wie möglich in den Cache passen und gleichzeitig die Bandbreite minimieren.
Jed

206

Ich denke, der Ausdruck "vorzeitige Optimierung ist die Wurzel allen Übels" wird weit überstrapaziert. Für viele Projekte ist es eine Ausrede geworden, die Leistung erst spät in einem Projekt zu berücksichtigen.

Dieser Satz ist oft eine Krücke für Menschen, um Arbeit zu vermeiden. Ich sehe diesen Satz verwendet, wenn die Leute wirklich sagen sollten: "Gee, wir haben wirklich nicht daran gedacht und haben jetzt keine Zeit, uns damit zu befassen."

Ich habe viel mehr "lächerliche" Beispiele für dumme Leistungsprobleme gesehen als Beispiele für Probleme, die aufgrund von "Pessimisierung" eingeführt wurden.

  • Lesen des gleichen Registrierungsschlüssels tausende (oder zehntausende) Mal während des Programmstarts.
  • Laden Sie dieselbe DLL hunderte oder tausende Male
  • Verschwenden Sie Mega-Bytes an Speicher, indem Sie die vollständigen Pfade zu Dateien unnötig beibehalten
  • Sie organisieren keine Datenstrukturen, sodass sie viel mehr Speicher beanspruchen als sie benötigen
  • Größe aller Zeichenfolgen, in denen Dateinamen oder Pfade zu MAX_PATH gespeichert sind
  • Kostenlose Abfrage nach Dingen, die Ereignisse, Rückrufe oder andere Benachrichtigungsmechanismen haben

Was ich für eine bessere Aussage halte, ist folgende: "Optimierung ohne Messen und Verstehen ist überhaupt keine Optimierung - es ist nur eine zufällige Änderung".

Gute Leistung ist zeitaufwändig - oft mehr als die Entwicklung des Features oder der Komponente selbst.


46
"Vorzeitig" ist das Schlüsselwort dieses Zitats. Ihre Umformulierung in "Optimierung ohne Messen und Verstehen" scheint die Bedeutung kein bisschen zu ändern. Genau das meinte Knuth.
Bill the Lizard

13
@ Foredecker: richtig auf. Zu viele Menschen den Kontext vergessen, die Puts das Zitat fest gegen Mikro -optimierung. Die Analyse eines Problems, um den richtigen Algorithmus auszuwählen, bevor es implementiert wird, ist nicht verfrüht, aber zu oft wird dieses Zitat hochgeworfen, um die faulste und ineffizienteste Lösung zu rechtfertigen.
Shog9

5
Es kommt wirklich auf den Einzelfall an, es gibt mehr Fälle, in denen vorzeitige Optimierung zum Problem wird, als unzureichende Optimierungsplanung zum Problem wird
Mark Rogers

12
-1: Es gibt einen Unterschied zwischen "Optimierung" und richtigem Design. Für diejenigen, die es nicht sagen können, ist eine gute Faustregel, dass eine "Optimierung" den Code schwieriger zu lesen macht, aber schneller oder effizienter. Ein besseres Design macht den Code leichter lesbar (oder zumindest nicht schlechter) und effizienter.
Ted

5
Wenn es viel zu stark genutzt wird, ist die Bevölkerung, die Fragen zu SO stellt, stark auf die Ausreißer ausgerichtet. : D
dkretz

114

Datenbanken sind Pessimierungsspielland.

Zu den Favoriten gehören:

  • Teilen Sie eine Tabelle in Vielfache auf (nach Datumsbereich, alphabetischem Bereich usw.), da sie "zu groß" ist.
  • Erstellen Sie eine Archivtabelle für zurückgezogene Datensätze, fahren Sie jedoch mit der Produktionstabelle mit UNION fort.
  • Duplizieren Sie ganze Datenbanken nach (Abteilung / Kunde / Produkt / etc.)
  • Widerstehen Sie dem Hinzufügen von Spalten zu einem Index, da dieser zu groß wird.
  • Erstellen Sie viele Übersichtstabellen, da die Neuberechnung aus Rohdaten zu langsam ist.
  • Erstellen Sie Spalten mit Unterfeldern, um Platz zu sparen.
  • Denormalisieren Sie in Felder als Array.

Das ist mir ein Rätsel.


Sich der Notwendigkeit einer Indexierung zu widersetzen, ist nur schmerzhaft zu überlegen.
Bill the Lizard

2
Ja, ich kenne jemanden, der für eine große US-Ölgesellschaft arbeitet, der fast allen Tabellen eine Archivtabelle zugeordnet ist, und die meisten Abfragen wählen aus Ansichten aus, die die Tabellenpaare UNIONIEREN. Leistung ist wie erwartet!
Tony Andrews

Hah, ich denke, jeder DBA muss irgendwann die Union mit der Archivtabellenroute durchlaufen haben. Es scheint zu der Zeit immer so vernünftig.
Cruachan

3
Ich füge hinzu: Teilen Sie die Datenbank in mehrere verschiedene Datenbanken (Kunden ac, Kunden df usw.)
Gabriele D'Antona

Könnten Sie näher auf "Denormalisieren in Felder als Array" eingehen? Was meinst du hier?
Bart van Heukelom

87

Ich denke, es gibt keine absolute Regel: Einige Dinge werden am besten im Voraus optimiert, andere nicht.

Ich habe zum Beispiel in einer Firma gearbeitet, in der wir Datenpakete von Satelliten erhalten haben. Jedes Paket hat viel Geld gekostet, daher wurden alle Daten stark optimiert (dh gepackt). Zum Beispiel wurde Breiten- / Längengrad nicht als Absolutwerte (Floats) gesendet, sondern als Offsets relativ zur "Nordwesten" -Ecke einer "aktuellen" Zone. Wir mussten alle Daten entpacken, bevor sie verwendet werden konnten. Aber ich denke, dies ist keine Pessimierung, sondern eine intelligente Optimierung, um die Kommunikationskosten zu senken.

Andererseits haben unsere Softwarearchitekten entschieden, dass die entpackten Daten in ein gut lesbares XML-Dokument formatiert und als solches in unserer Datenbank gespeichert werden sollten (im Gegensatz dazu, dass jedes Feld in einer entsprechenden Spalte gespeichert wird). Ihre Idee war, dass "XML die Zukunft ist", "Speicherplatz ist billig" und "Prozessor ist billig", so dass nichts optimiert werden musste. Das Ergebnis war, dass unsere 16-Byte-Pakete in 2-KB-Dokumente umgewandelt wurden, die in einer Spalte gespeichert waren, und dass wir selbst für einfache Abfragen Megabyte an XML-Dokumenten in den Speicher laden mussten! Wir haben über 50 Pakete pro Sekunde erhalten, sodass Sie sich vorstellen können, wie schrecklich die Leistung wurde (übrigens, das Unternehmen ging bankrott).

Es gibt also wieder keine absolute Regel. Ja, manchmal ist eine zu frühe Optimierung ein Fehler. Aber manchmal ist das Motto "CPU / Speicherplatz / Speicher ist billig" die wahre Wurzel allen Übels.


37
Ich bin damit einverstanden, dass "CPU / Speicherplatz / Speicher billig ist" die wahre Wurzel allen Übels ist. +1
ksuralta

5
Ich habe gehört, dass XML auch drivel. Eine andere Tankfirma.
n8wrl

19
@ksuralta: "CPU / Speicherplatz / Speicher ist billig" ist eine bequeme Ausrede, um Gedanken zu vermeiden. Das Vermeiden von Gedanken ist die imaginäre Wurzel allen Übels.
Piskvor verließ das Gebäude am

Diese XML-Analyse fand auch an meinem Arbeitsplatz statt, gefolgt von JSONization. Alles, um ein "mühsames" relationales Datenbankdesign zu vermeiden.
Tanz87

75

Oh mein Gott, ich glaube ich habe sie alle gesehen. Meistens ist es eine Anstrengung, Leistungsprobleme von jemandem zu beheben, der zu faul ist, um Fehler bis zur URSACHE dieser Leistungsprobleme zu beheben oder sogar zu untersuchen, ob tatsächlich ein Leistungsproblem vorliegt. In vielen dieser Fälle frage ich mich, ob es nicht nur darum geht, dass diese Person eine bestimmte Technologie ausprobieren möchte und verzweifelt nach einem Nagel sucht, der zu ihrem glänzenden neuen Hammer passt.

Hier ist ein aktuelles Beispiel:

Der Datenarchitekt kommt zu mir mit einem ausführlichen Vorschlag, eine Schlüsseltabelle in einer ziemlich großen und komplexen Anwendung vertikal zu partitionieren. Er möchte wissen, welche Art von Entwicklungsaufwand notwendig wäre, um sich auf die Veränderung einzustellen. Das Gespräch lief folgendermaßen ab:

Ich: Warum denkst du darüber nach? Was ist das Problem, das Sie lösen möchten?

Ihm: Tabelle X ist zu breit, wir partitionieren sie aus Leistungsgründen.

Ich: Warum denkst du, dass es zu breit ist?

Ihm: Der Berater sagte, das seien viel zu viele Spalten, um sie in einer Tabelle zu haben.

Ich: Und das wirkt sich auf die Leistung aus?

Ihm: Ja, Benutzer haben zeitweise Verlangsamungen im XYZ-Modul der Anwendung gemeldet.

Ich: Woher wissen Sie, dass die Breite der Tabelle die Ursache des Problems ist?

Ihm: Das ist die Schlüsseltabelle, die vom XYZ-Modul verwendet wird, und sie entspricht 200 Spalten. Es muss das Problem sein.

Ich (Erklären): Das Modul XYZ verwendet jedoch insbesondere die meisten Spalten in dieser Tabelle, und die verwendeten Spalten sind unvorhersehbar, da der Benutzer die App so konfiguriert, dass die Daten angezeigt werden, die aus dieser Tabelle angezeigt werden sollen. Es ist wahrscheinlich , dass 95% der Zeit würden wir alle die Tische wieder zusammen sowieso Verbindungs aufzuwickeln , was würde verletzt Leistung.

Ihm: Der Berater sagte, es sei zu breit und wir müssen es ändern.

Ich: Wer ist dieser Berater? Ich wusste nicht, dass wir einen Berater eingestellt haben, und sie haben überhaupt nicht mit dem Entwicklungsteam gesprochen.

Ihm: Nun, wir haben sie noch nicht eingestellt. Dies ist Teil eines Vorschlags, den sie angeboten haben, aber sie bestanden darauf, dass wir diese Datenbank neu gestalten müssen.

Ich: Ähhh. Der Berater, der Dienstleistungen zur Neugestaltung von Datenbanken verkauft, ist der Meinung, dass wir eine Neugestaltung der Datenbank benötigen.

Das Gespräch ging so weiter und weiter. Danach habe ich mir die fragliche Tabelle noch einmal angesehen und festgestellt, dass sie wahrscheinlich durch eine einfache Normalisierung eingegrenzt werden kann, ohne dass exotische Partitionierungsstrategien erforderlich sind. Dies stellte sich natürlich als strittiger Punkt heraus, als ich die Leistungsprobleme (zuvor nicht gemeldet) untersuchte und sie auf zwei Faktoren zurückführte:

  1. Fehlende Indizes für einige Schlüsselspalten.
  2. Einige betrügerische Datenanalysten, die regelmäßig Schlüsseltabellen (einschließlich der "zu breiten") sperrten, indem sie die Produktionsdatenbank direkt mit MSAccess abfragten.

Natürlich drängt der Architekt immer noch auf eine vertikale Aufteilung des Tisches, die am "zu breiten" Metaproblem festhält. Er unterstützte seinen Fall sogar, indem er einen Vorschlag von einem anderen Datenbankberater erhielt, der feststellen konnte, dass wir größere Designänderungen an der Datenbank benötigten, ohne auf die App zu schauen oder eine Leistungsanalyse durchzuführen.


Aaag MSAccess zu prod. Wir haben eine Prozedur geschrieben, um alle Zugriffsverbindungen alle paar Minuten zu trennen, bis wir endlich die Nachricht erhalten haben, dass es schlecht war.
Nat

1
Wir hatten einen ähnlichen Job, der jedoch nicht mehr genutzt wurde. Um fair zu sein, ist Access nicht das Problem, sondern macht es Neulingen einfach, nicht leistungsfähige Abfragen zu erstellen / auszuführen.
JohnFx

Wir sind in unserem Unternehmen von älteren Ad-hoc-Zugriffsverbindungen zur Produktionsdatenbank abhängig. Nichts wie ein paar gelegentliche SQL'er, die eine WHERE-Klausel vergessen und die Haupttabellen blockieren!
HardCode

35
"Ich habe gehört, lila hat den meisten RAM"
Piskvor verließ das Gebäude am

Es könnte schlimmer sein. Der Excel-Abfrage-Editor sperrt bei Verwendung die gesamte Datenbank. Als ich nichts davon wusste, ließ ich eine Instanz für den größten Teil des Tages offen, während ich in etwas anderem arbeitete. Das Schlimmste ist, dass MS SQL Server nicht den richtigen Benutzernamen / Computer gemeldet hat, der die Sperre vorgenommen hat. Stunden später wurde mir klar, dass ich der Grund für das Sperren war, weil die gesperrten Tabellen Teil der Ansicht waren, die ich abfragte und alles andere zuerst überprüft hatte.
Esteban Küber

58

Ich habe Leute gesehen, die Alphadrive-7 verwendeten, um CHX-LT vollständig zu inkubieren. Dies ist eine ungewöhnliche Praxis. Die üblichere Praxis besteht darin, den ZT-Transformator so zu initialisieren, dass die Pufferung verringert wird (aufgrund eines höheren Nettoüberlastungswiderstands) und Bytegraphien im Java-Stil zu erstellen.

Total pessimistisch!


10
Vielleicht haben sie versucht, den Flusskondensator zu verstärken
Mikeage

6
Im Grunde genommen ist das einzige neue Prinzip, dass Energie nicht durch die Relativbewegung von Leitern und Flüssen erzeugt wird, sondern durch die modiale Wechselwirkung von Magneto-Reluktanz und kapazitiver Dauer.
Matt Rogish

17
+1 weil mein Monitor sowieso gereinigt werden musste ;-)
RBerteig

1
Verdammt!! Aber was ist mit der ekletromagentisch-genetischen Wirkung? Ich denke, es sollte auch berücksichtigt werden. Oder das Motiv verwandelt sich in einen Zombie.
Suraj Chandran

1
Drei Wörter: "Chromschalldämpferlager."
Allbite

53

Ich gebe zu, nichts Erderschütterndes, aber ich habe Leute erwischt, die StringBuffer verwenden, um Strings außerhalb einer Schleife in Java zu verketten. Es war so einfach wie sich zu drehen

String msg = "Count = " + count + " of " + total + ".";

in

StringBuffer sb = new StringBuffer("Count = ");
sb.append(count);
sb.append(" of ");
sb.append(total);
sb.append(".");
String msg = sb.toString();

Früher war es üblich, die Technik in einer Schleife anzuwenden, da sie messbar schneller war. Die Sache ist, StringBuffer ist synchronisiert, so dass es tatsächlich zusätzlichen Aufwand gibt, wenn Sie nur ein paar Strings verketten. (Ganz zu schweigen davon, dass der Unterschied auf dieser Skala absolut trivial ist.) Zwei weitere Punkte zu dieser Praxis:

  1. StringBuilder ist nicht synchronisiert und sollte daher StringBuffer vorgezogen werden, wenn Ihr Code nicht von mehreren Threads aufgerufen werden kann.
  2. Moderne Java-Compiler verwandeln lesbare String-Verkettung in optimierten Bytecode für Sie, wenn dies ohnehin angemessen ist.

3
Erstens: Warum würden Sie nicht mindestens Java 5 verwenden? Zweitens: Ja, das kannst du. Wie kommt es, dass Sie im ersten Beispiel bis 5 zählen können, im zweiten nicht? Es werden dieselben String-Literale wie beim ersten verwendet. Schreiben Sie lesbaren Code und lassen Sie den Compiler entscheiden, wann StringBuffer hinter den Kulissen verwendet werden soll.
Bill the Lizard

4
@ MetroidFan2002: Die String-Literale im zweiten Beispiel sind ebenfalls Objekte. Wie ich in der Antwort sagte, sind die Unterschiede in dieser Größenordnung trivial.
Bill the Lizard

1
Das bedeutet nicht, dass jeder String durch einen eigenen StringBuffer ersetzt wird. Die vom Compiler durchgeführte Optimierung reduziert die Anzahl der erstellten Objekte.
Bill the Lizard

3
@Eric: String msg = "Count =" + count + "von" + total + "."; wird in Java häufig zu String msg = new StringBuffer () kompiliert. append ("Count"). append (count) .append ("of") .append (total) .append ("."). toString (); ... genau das macht das zweite Beispiel.
Grant Wagner

3
Herr Wagner, Sie müssen sich all diese Methodenaufrufe ansehen, nicht den Compiler. Sie müssen sie schreiben und später verstehen. Der Compiler macht sowieso das Gleiche. Daher ist in diesem Fall die Lesbarkeit wichtiger.
Ypnos

47

Ich habe einmal eine MSSQL-Datenbank gesehen, die eine 'Root'-Tabelle verwendet hat. Die Root-Tabelle hatte vier Spalten: GUID (Uniqueidentifier), ID (Int), LastModDate (Datum / Uhrzeit) und CreateDate (Datum / Uhrzeit). Alle Tabellen in der Datenbank wurden mit einem Fremdschlüssel für die Root-Tabelle versehen. Wann immer eine neue Zeile in einer Tabelle in der Datenbank erstellt wurde, mussten Sie einige gespeicherte Prozeduren verwenden, um einen Eintrag in die Root-Tabelle einzufügen, bevor Sie zu der eigentlichen Tabelle gelangen konnten, die Ihnen wichtig war (und nicht zu der Datenbank, für die der Job ausgeführt wurde) Sie mit ein paar Auslösern einfache Auslöser).

Dies verursachte ein Durcheinander von nutzlosem Abhören und Kopfschmerzen, erforderte alles, was darüber geschrieben war, um Sprocs zu verwenden (und beseitigte meine Hoffnungen, LINQ in das Unternehmen einzuführen. Es war möglich, aber die Kopfschmerzen nicht wert), und um das Ganze abzurunden, tat es nicht. Ich kann nicht einmal das erreichen, was es tun sollte.

Der Entwickler, der diesen Pfad gewählt hat, hat ihn unter der Annahme verteidigt, dass dies viel Platz gespart hat, weil wir keine Guids für die Tabellen selbst verwendet haben (aber ... wird nicht für jede von uns erstellte Zeile eine GUID in der Root-Tabelle generiert?) , verbesserte irgendwie die Leistung und machte es "einfach", Änderungen an der Datenbank zu überwachen.

Oh, und das Datenbankdiagramm sah aus wie eine mutierte Spinne aus der Hölle.


42

Wie wäre es mit POBI - Pessimisierung offensichtlich absichtlich?

Mein Kollege in den 90er Jahren hatte es satt, vom CEO in den Arsch getreten zu werden, nur weil der CEO den ersten Tag jeder ERP-Software-Version (eine benutzerdefinierte) damit verbracht hatte, Leistungsprobleme in den neuen Funktionen zu lokalisieren. Selbst wenn die neuen Funktionen Gigabyte knirschten und das Unmögliche möglich machten, fand er immer ein Detail oder sogar ein scheinbar großes Problem, über das er jammern konnte. Er glaubte viel über das Programmieren zu wissen und bekam seine Tritte, indem er Programmierern in den Arsch trat.

Aufgrund der Inkompetenz der Kritik (er war ein CEO, kein IT-Mann) gelang es meinem Kollegen nie, es richtig zu machen. Wenn Sie kein Leistungsproblem haben, können Sie es nicht beseitigen ...

Bis zu einer Veröffentlichung hat er viele Delay (200) -Funktionsaufrufe (es war Delphi) in den neuen Code eingefügt. Es dauerte nur 20 Minuten nach der Inbetriebnahme, und er wurde angewiesen, im Büro des CEO zu erscheinen, um seine überfälligen Beleidigungen persönlich zu holen.

Bisher war es nur ungewöhnlich, dass meine Kollegen stumm waren, als er zurückkam, lächelte, scherzte, ein oder zwei BigMacs ausging, während er normalerweise gegen Tische trat, über den CEO und das Unternehmen flammte und den Rest des Tages zu Tode verbrachte .

Natürlich ruhte sich mein Kollege jetzt ein oder zwei Tage an seinem Schreibtisch aus und verbesserte seine Zielfähigkeiten in Quake. Am zweiten oder dritten Tag löschte er die Verzögerungsaufrufe, baute sie neu auf und veröffentlichte einen "Notfall-Patch", von dem er das Wort verbreitete dass er 2 Tage und 1 Nacht verbracht hatte, um die Leistungslöcher zu reparieren.

Dies war das erste (und einzige) Mal, dass der böse CEO "großartige Arbeit!" Sagte. zu ihm. Das ist alles was zählt, oder?

Das war echtes POBI.

Es ist aber auch eine Art Optimierung sozialer Prozesse, also 100% in Ordnung.

Meiner Ansicht nach.


10
Ich erinnere mich an jemanden, der über eine Datenverarbeitungs-App schrieb, die auf verschiedenen Ebenen verkauft wurde, wo der "Lite" nur wenige Datensätze pro Sekunde verarbeiten konnte, die "Superduper" -Version Tausende. Der einzige Unterschied im Quellcode ist der von Sleep (N).
Peterchen

1
Brillant! Ich würde diesen Standard in einer solchen Situation empfehlen. Weisen Sie zu Beginn der Entwicklung einen großen Teil des Speichers zu und fügen Sie einige Schlafaufrufe hinzu. Wenn Sie eine gewisse Leistung erzielen möchten, können Sie diese einfach reduzieren. Es heißt, ein Wundertäter zu sein;)
RCIX

Leider ist das Patchen von Sleeps auf NOPs einfach, so dass die Lite-Version sehr leicht geknackt werden kann. Diese "Optimierungs" -Reserve erfordert möglicherweise einen ausführbaren Packer, um das Debuggen und Patchen zu erschweren.
TheBlastOne

32

"Datenbankunabhängigkeit". Dies bedeutete keine gespeicherten Prozesse, Trigger usw. - nicht einmal Fremdschlüssel.


8
Ist diese "Unabhängigkeit" in dem Sinne, dass Sie sich so weit über der Datenbank befinden, dass Sie vergessen haben, was Daten sind? Unnötig über Datenbanken zu abstrahieren, "um Migrationsprobleme zu vermeiden", ist ein Ärgernis für Haustiere. du wirst es nicht brauchen.
Rob

8
Ja schon. Architekturastronauten bei der Arbeit. Ich habe Web-Apps erstellt, seit es ein Web gab, und in all dieser Zeit bin ich nie von einer Datenbankplattform auf eine andere gewechselt.
Chris

5
Ich bin mir sicher, dass es passiert, aber es ist selten genug, dass Sie ein Idiot sind, wenn Sie Ihre Architektur nach dieser Möglichkeit gestalten.
Chris

6
Harpo, das ist eine andere Situation - in diesem Fall ist es eine Voraussetzung. Ich spreche davon, wenn es keine Anforderung ist, aber die AA entscheidet, dass es irgendwann "sein könnte".
Chris

3
@All: DB-Unabhängigkeit kann Sie kosten, ja, aber unser Produkt wird in Umgebungen ausgeführt, in denen der DB-Anbieter durch Gebote ausgewählt wird, und wir müssen grundsätzlich mitspielen. Einige Entwickler haben nicht den Luxus eines vertikal integrierten Software-Stacks und müssen trotzdem auskommen.
Chris R

31
var stringBuilder = new StringBuilder();
stringBuilder.Append(myObj.a + myObj.b + myObj.c + myObj.d);
string cat = stringBuilder.ToString();

Beste Verwendung eines StringBuilder, den ich je gesehen habe.


9
Sprechen Sie über "unklar über das Konzept"! Beeindruckend!
Eddie

3
Cool. "Mein Lead sagt, dass ich die StringBuilder-Klasse verwenden muss, wenn ich Strings verketten möchte. Das ist, was ich tue. Also, was ist los?" Lol ...
TheBlastOne

26

Verwenden eines regulären Ausdrucks zum Teilen eines Strings, wenn ein einfacher string.split ausreicht


25
ABER in Java String.Split verwendet einen regulären Ausdruck!
Frank Krueger

Ich sehe nicht, wie ein Regex so schnell sein kann wie ein interner String-Split.
Andrei Rînea

2
Die gezielte Suche nach einem regulären Ausdruck, der zum Teilen von Zeichenfolgen verwendet wird, und zum Ersetzen durch eine "einfache" Teilungsfunktion klingt jedoch nach einem perfekten Beispiel für Pessimisierung. Regex-Bibliotheken sind schnell genug.
David Crawshaw

5
@ David Crawshaw: Die Suche nach Möglichkeiten zur Mikrooptimierung verschwendet menschliche Zeit. Verwenden Sie beim Schreiben von Code die am wenigsten komplexe Lösung.
Piskvor verließ das Gebäude

6
-1: Wenn Sie an Regexes gewöhnt sind, ist es sehr natürlich, dies zu schreiben, anstatt sich an die 1001 sprachinternen String-Manipulatoren zu gewöhnen.
KillianDS

26

Sehr spät zu diesem Thread weiß ich, aber ich habe das kürzlich gesehen:

bool isFinished = GetIsFinished();

switch (isFinished)
{
    case true:
        DoFinish();
        break;

    case false:
        DoNextStep();
        break;

    default:
        DoNextStep();
}

Weißt du, nur für den Fall, dass ein Boolescher Wert einige zusätzliche Werte hat ...


22
Richtig, falsch ein FileNotFound natürlich
Ikke

Hey, du solltest immer einen Standard / case else / etc. Haben. Was passiert, wenn eine kluge Person diesen Booleschen Wert in eine Aufzählung ändert, um einen anderen Status wiederzugeben? Dann fügt die nächste Person die Aufzählung hinzu und vergisst, die Prozedur zu ändern? Ein Standardwert, bei dem Sie keine Ausführungszeit und nur sehr wenig Entwicklungszeit benötigen. Aufspüren eines versehentlich eingeführten logischen Fehlers, der zur Laufzeit auftritt ... Das kostet Zeit, Geld und Reputation. Gleich getan ist viel gespart.
Oorang

1
@Oorang ... warum solltest du es überhaupt als Schalter haben? Es ist ein Boolescher Wert - ein Wenn / Sonst ist alles, was benötigt wird.
Damovisa

@Damovisa facepalm richtig ... sehr gut , dann :) Missed dass :)
Oorang

2
Es war nullable <Boolean> ... :)
George Chakhidze

25

Das schlechteste Beispiel, das ich mir vorstellen kann, ist eine interne Datenbank in meinem Unternehmen, die Informationen zu allen Mitarbeitern enthält. Es erhält ein nächtliches Update von HR und verfügt über einen ASP.NET-Webdienst. Viele andere Apps verwenden den Webdienst, um beispielsweise Such- / Dropdown-Felder zu füllen.

Der Pessimismus besteht darin, dass der Entwickler der Meinung war, dass wiederholte Aufrufe des Webdienstes zu langsam wären, um wiederholte SQL-Abfragen durchzuführen. Also, was hat er getan? Das Anwendungsstartereignis liest die gesamte Datenbank ein und konvertiert alles in Objekte im Speicher, die unbegrenzt gespeichert werden, bis der App-Pool wiederverwendet wird. Dieser Code war so langsam, dass das Laden von weniger als 2000 Mitarbeitern 15 Minuten dauern würde. Wenn Sie den App-Pool tagsüber versehentlich recycelt haben, kann dies 30 Minuten oder länger dauern, da bei jeder Webdienstanforderung mehrere gleichzeitige Neuladungen gestartet werden. Aus diesem Grund würden neue Mitarbeiter am ersten Tag der Kontoerstellung nicht in der Datenbank angezeigt und könnten daher in den ersten Tagen nicht auf die meisten internen Apps zugreifen und mit den Daumen drehen.

Die zweite Stufe des Pessimismus besteht darin, dass der Entwicklungsmanager ihn nicht berühren möchte, weil er befürchtet, abhängige Anwendungen zu beschädigen. Dennoch kommt es aufgrund des schlechten Designs einer so einfachen Komponente weiterhin zu sporadischen unternehmensweiten Ausfällen kritischer Anwendungen.


28
Management vom Feinsten - "Nein, lassen Sie uns nicht einmal 80 Programmierstunden in die Reparatur dieser App investieren, das ist zu teuer. Behalten wir es einfach bei, damit seine Fehler mehr als 200 Benutzerstunden pro Monat plus 10 Programmierstunden pro Monat verbrauchen können 'Instandhaltung'." AAAAAAAAAUGH !!!
Piskvor verließ das Gebäude am

25

Niemand scheint das Sortieren erwähnt zu haben, also werde ich es tun.

Ich habe mehrmals festgestellt, dass jemand einen Bubblesort von Hand hergestellt hat, weil die Situation keinen Aufruf des bereits existierenden "zu ausgefallenen" Quicksort-Algorithmus "nicht erforderte". Der Entwickler war zufrieden, als sein handgefertigter Bubblesort gut genug für die zehn Datenzeilen funktionierte, die er zum Testen verwendet. Es ging nicht ganz so gut, nachdem der Kunde ein paar tausend Zeilen hinzugefügt hatte.


2
Ich habe das selbst einmal gemacht, als ich feststellte, dass typischerweise n = 2 ist. Spätere Produktverbesserungen machten meine Prämisse ungültig und der Code wurde durch PDQ ersetzt.
Mark Ransom

2
Ja, aber es ist schön, ab und zu etwas Algorythmisches zu schreiben ;)
UpTheCreek

20

Ich habe einmal an einer App gearbeitet, die voller Code war:

 1 tuple *FindTuple( DataSet *set, int target ) {
 2     tuple *found = null;
 3     tuple *curr = GetFirstTupleOfSet(set);
 4     while (curr) {
 5         if (curr->id == target)
 6             found = curr;
 7         curr = GetNextTuple(curr);
 8     }
 9     return found;
10 }

Einfach entfernen found, nullam Ende zurückkehren und die sechste Zeile ändern in:

            return curr;

Verdoppelte die App-Leistung.


1
Ich habe einmal in einem Unternehmen gearbeitet, in dem die Kodierungsrichtlinien "nur eine Rückgabe am Ende" forderten (zur Wartung). Und in der Tat, einige spucken Code wie Ihren aus, weil sie nicht denken (die offensichtliche Lösung bestand meistens darin, ein goto zum proc-Ausgang zu verwenden oder die Ausgangsbedingung von Schleifen zu
ändern

12
Ein Rücklauf erzeugt hier ein deutlich anderes Verhalten. Wenn Sie curr zurückgeben, erhalten Sie die ERSTE Übereinstimmung, wobei der von Ihnen eingefügte Code die LETZTE Übereinstimmung zurückgibt.
SoapBox

2
@ SoapBox: Du hast recht. @Dour High Arch: Die Leistungssteigerung hatte nichts mit der Single-Return-Regel zu tun, da Flolo sagte, dass das Ändern der Schleifenbedingung (curr &&! Found) den gleichen Effekt haben würde. GOTO zum Proc-Ausgang ist schrecklich und macht den Zweck der Single-Return-Richtlinie zunichte.
Akusete

2
Gute Kommentare an alle. In diesem Fall sollte es nur ein einziges Tupel mit jeder ID geben.
Dour High Arch

7
Das ist aber keine "Pessimisierung", oder? Es ist einfach eine Optimierung, die darauf wartet, durchgeführt zu werden.
Tim Long

20

Ich musste einmal versuchen, Code zu ändern, der diese Edelsteine ​​in der Constants-Klasse enthielt

public static String COMMA_DELIMINATOR=",";
public static String COMMA_SPACE_DELIMINATOR=", ";
public static String COLIN_DELIMINATOR=":";

Jedes davon wurde im Rest der Anwendung mehrfach für unterschiedliche Zwecke verwendet. COMMA_DELIMINATOR hat den Code mit über 200 Verwendungen in 8 verschiedenen Paketen übersät.


Zumindest so etwas ist leicht aus der Quelle zu finden / zu ersetzen - trotzdem meine Sympathien.
Erik Forbes

12
Auch - Deliminator? Ich dachte, es wäre "Trennzeichen". Deliminator klingt wie ein schlechter Film Mitte der 90er Jahre, der irgendwie 3 Fortsetzungen hat ...........
Erik Forbes

53
Deliminator III: Aufstieg der Kommas
Rob

33
In einem weiteren Punkt freue ich mich über die richtige Abgrenzung von Colins. Jeder Programmierer, der sein Salz wert ist, weiß, dass wenn es eine Sache gibt, die Sie unbedingt richtig trennen müssen, es die verdammten Colins sind.
Rob

2
Es ist nicht so einfach, richtig zu finden und zu ersetzen. Da jeder für unterschiedliche Zwecke verwendet wird. Jeder gute Programmierer hätte zumindest so etwas getan: COUNTRY_LIST_DELIM = ... CLASSIFICATION_DELIM = ... etc
KitsuneYMG

19

Die große Nummer eins aller Zeiten, die mir in der Inhouse-Software immer wieder begegnet:

Die Funktionen des DBMS werden aus Gründen der "Portabilität" nicht verwendet, da "wir später möglicherweise zu einem anderen Anbieter wechseln möchten".

Lies meine Lippen. Für jede Inhouse-Arbeit: ES PASSIERT NICHT!


9
Es passiert. MySQL -> postgresql, also haben wir nichts verloren .
Thomas

Oder postgres / postgis -> sqlite / Spatialite ... Das war ein Schmerz im Arsch ...
Philip

es passiert in JUnit-Tests
kachanov

17

Ich hatte einen Kollegen, der versuchte, den Optimierer unseres C-Compilers zu überlisten und routinemäßig Code neu zu schreiben, den nur er lesen konnte. Einer seiner Lieblingstricks war das Ändern einer lesbaren Methode wie (Code erstellen):

int some_method(int input1, int input2) {
    int x;
    if (input1 == -1) {
        return 0;
    }
    if (input1 == input2) {
        return input1;
    }
    ... a long expression here ...
    return x;
}

das mögen:

int some_method() {
    return (input == -1) ? 0 : (input1 == input2) ? input 1 :
           ... a long expression ...
           ... a long expression ...
           ... a long expression ...
}

Das heißt, die erste Zeile einer einmal lesbaren Methode würde "return " werden und jede andere Logik würde durch tief verschachtelte terniäre Ausdrücke ersetzt. Wenn Sie darüber streiten wollten, dass dies nicht wartbar ist, hat er darauf hingewiesen, dass die Montageausgabe seiner Methode drei oder vier Montageanweisungen kürzer war. Es war nicht unbedingt schneller, aber es war immer winzig bisschen kürzer. Dies war ein eingebettetes System, bei dem die Speichernutzung gelegentlich eine Rolle spielte, aber es gab weitaus einfachere Optimierungen, die vorgenommen werden konnten, als dies, was den Code lesbar gemacht hätte.

Danach entschied er aus irgendeinem Grund, dass dies ptr->structElementzu unlesbar sei, und begann, all dies in (*ptr).structElementdie Theorie umzuwandeln, dass es auch lesbarer und schneller sei.

Lesen von lesbarem Code in unlesbaren Code für höchstens 1% Verbesserung und manchmal sogar langsameren Code.


Wenn dieses Modul millionenfach pro Schleife aufgerufen wird, würde ich diese Optimierung gutheißen, solange er das verdammt noch mal kommentiert.
Michael Dorgan

2
@ Michael: Ich würde nicht, es sei denn, es gab Messungen, die zeigten, dass es schneller war , nicht nur kürzer .
Dsimcha

In den meisten Situationen ist der ternäre Operator besser lesbar als if. Beharren auf Aussagen über Ausdrücke in C ist es, kulturelle / religiöse Dogma, nicht jede Art von Ziel Praxis. (Bessere Richtlinie: Wenn das verschachtelte Ternär zu lang zum Lesen ist, sollten Sie es auch nicht verwenden if.)
Leushenko

2
Hier geht es darum, eine gesamte Funktion zu übernehmen und durch eine einzelne Anweisung, eine Rückgabe, zu ersetzen, wodurch die gesamte Logik der gesamten Funktion durch verschachtelte Ternäre ersetzt wird. Wenn Sie es sehen würden, würden Sie verstehen. Dies ist keine religiöse Sache "Ich hasse ternäre Operatoren". Ich spreche nicht davon, eine einzelne ifFunktion zu übernehmen und durch eine ternäre zu ersetzen. Das ist in Ordnung und oft besser lesbar. Ich spreche über das Ersetzen einer Methode mit mehr als 30 Zeilen durch eine einzelne return-Anweisung und verschachtelte ternäre. Niemand dachte, der neue Code sei besser lesbar, aber ein Entwickler dachte, er sei schneller.
Eddie

15

In einem meiner ersten Jobs als vollwertiger Entwickler übernahm ich ein Projekt für ein Programm, bei dem Skalierungsprobleme auftraten. Es würde bei kleinen Datenmengen recht gut funktionieren, bei großen Datenmengen jedoch vollständig abstürzen.

Als ich mich vertiefte, stellte ich fest, dass der ursprüngliche Programmierer versuchte, die Dinge durch Parallelisierung der Analyse zu beschleunigen - indem er für jede zusätzliche Datenquelle einen neuen Thread startete. Er hatte jedoch einen Fehler gemacht, da für alle Threads eine gemeinsame Ressource erforderlich war, für die sie festgefahren waren. Natürlich sind alle Vorteile der Parallelität verschwunden. Darüber hinaus stürzten die meisten Systeme ab, um mehr als 100 Threads zu starten, nur um alle bis auf einen zu sperren. Meine bullige Entwicklungsmaschine war insofern eine Ausnahme, als sie in etwa 6 Stunden einen Datensatz mit 150 Quellen durchlief.

Um das Problem zu beheben, habe ich die Multithreading-Komponenten entfernt und die E / A bereinigt. Ohne weitere Änderungen fiel die Ausführungszeit für das 150-Quellen-Dataset auf meinem Computer unter 10 Minuten und auf dem durchschnittlichen Unternehmenscomputer von unendlich auf unter eine halbe Stunde.


Ich verhindere nur, dass dies heute in einem Projekt passiert. Jetzt weiß ich, dass ich die gute Wahl getroffen habe.
Deadalnix

14

Ich nehme an, ich könnte dieses Juwel anbieten:

unsigned long isqrt(unsigned long value)
{
    unsigned long tmp = 1, root = 0;
    #define ISQRT_INNER(shift) \
    { \
        if (value >= (tmp = ((root << 1) + (1 << (shift))) << (shift))) \
        { \
            root += 1 << shift; \
            value -= tmp; \
        } \
    }

    // Find out how many bytes our value uses
    // so we don't do any uneeded work.
    if (value & 0xffff0000)
    {
        if ((value & 0xff000000) == 0)
            tmp = 3;
        else
            tmp = 4;
    }
    else if (value & 0x0000ff00)
        tmp = 2;

    switch (tmp)
    {
        case 4:
            ISQRT_INNER(15);
            ISQRT_INNER(14);
            ISQRT_INNER(13);
            ISQRT_INNER(12);
        case 3:
            ISQRT_INNER(11);
            ISQRT_INNER(10);
            ISQRT_INNER( 9);
            ISQRT_INNER( 8);
        case 2:
            ISQRT_INNER( 7);
            ISQRT_INNER( 6);
            ISQRT_INNER( 5);
            ISQRT_INNER( 4);
        case 1:
            ISQRT_INNER( 3);
            ISQRT_INNER( 2);
            ISQRT_INNER( 1);
            ISQRT_INNER( 0);
    }
#undef ISQRT_INNER
    return root;
}

Da die Quadratwurzel an einer sehr empfindlichen Stelle berechnet wurde, hatte ich die Aufgabe, nach einer Möglichkeit zu suchen, sie schneller zu machen. Dieses kleine Refactoring reduzierte die Ausführungszeit um ein Drittel (für die Kombination aus Hardware und verwendetem Compiler YMMV):

unsigned long isqrt(unsigned long value)
{
    unsigned long tmp = 1, root = 0;
    #define ISQRT_INNER(shift) \
    { \
        if (value >= (tmp = ((root << 1) + (1 << (shift))) << (shift))) \
        { \
            root += 1 << shift; \
            value -= tmp; \
        } \
    }

    ISQRT_INNER (15);
    ISQRT_INNER (14);
    ISQRT_INNER (13);
    ISQRT_INNER (12);
    ISQRT_INNER (11);
    ISQRT_INNER (10);
    ISQRT_INNER ( 9);
    ISQRT_INNER ( 8);
    ISQRT_INNER ( 7);
    ISQRT_INNER ( 6);
    ISQRT_INNER ( 5);
    ISQRT_INNER ( 4);
    ISQRT_INNER ( 3);
    ISQRT_INNER ( 2);
    ISQRT_INNER ( 1);
    ISQRT_INNER ( 0);

#undef ISQRT_INNER
    return root;
}

Natürlich gibt es sowohl schnellere als auch bessere Möglichkeiten, dies zu tun, aber ich denke, es ist ein ziemlich gutes Beispiel für eine Pessimierung.

Edit: Kommen Sie und denken Sie darüber nach, die abgewickelte Schleife war eigentlich auch eine ordentliche Pessimisierung. Durch die Versionskontrolle kann ich auch die zweite Phase des Refactorings vorstellen, die sogar noch besser abschnitt als die oben genannten:

unsigned long isqrt(unsigned long value)
{
    unsigned long tmp = 1 << 30, root = 0;

    while (tmp != 0)
    {
        if (value >= root + tmp) {
            value -= root + tmp;
            root += tmp << 1;
        }
        root >>= 1;
        tmp >>= 2;
    }

    return root;
}

Dies ist genau der gleiche Algorithmus, wenn auch eine etwas andere Implementierung, also nehme ich an, dass er qualifiziert ist.


Ich nehme an, isqrt()berechnet floor(sqrt()), aber warum funktioniert dieser Code?
Pablo H

11

Dies kann auf einem höheren Niveau sein als das, wonach Sie gesucht haben, aber das Reparieren (wenn Sie erlaubt sind) beinhaltet auch ein höheres Maß an Schmerz:

Bestehen Sie darauf, einen Object Relationship Manager / eine Datenzugriffsschicht zu verwenden, anstatt eine der etablierten, getesteten und ausgereiften Bibliotheken zu verwenden (auch nachdem Sie darauf hingewiesen wurden).


Es ist nicht immer eine schlechte Idee, einen eigenen Code zu erstellen. Finden Sie, wie ein weiser Mann einmal sagte, die Abhängigkeiten und beseitigen Sie sie. Wenn es sich um eine Kerngeschäftsfunktion handelt, tun Sie es selbst.
Kibbee

Ich habe nie gefolgert, dass es immer eine schlechte Idee ist. Ich bezweifle, dass ORM / DAL-Zeug eine Kerngeschäftsfunktion ist, es sei denn, Sie sagen Frans Bouma oder ähnliches. Es ist äußerst ineffizient, eine eigene Entsprechung zu schreiben, bei der das (quadratische) Rad neu erfunden wird, was normalerweise auf das NIH-Syndrom zurückzuführen ist.
Gordon Hartley

@ Kibbee - ich stimme zu. Es ist besser, eigene Rollen zu erstellen und diese zu verstehen, als Abhängigkeiten von Drittanbietern zu verwenden. Wenn es kaputt geht (und es wird), können Sie es dann zumindest reparieren. Ich habe in der Vergangenheit Fehler in Hibernate und Apache Commons gefunden, die die Leistung unserer App absolut beeinträchtigten.
CodingWithSpike

4
Das Handrollen ist wirklich Ihre einzige Option, wenn keine der etablierten eine wichtige Funktion hat, die Sie benötigen.
Statik

3
In Anbetracht einiger der obigen Kommentare, etwas mehr Perspektive: Eine andere Pessimisierung besteht darin, zu versuchen, das ORM dazu zu bringen, absolut alles zu tun. Es ist oft nützlich für 95% + der Fälle. Für diese letzten 5% ist es viel einfacher, auf handgefertigten Persistenzcode / direkte Aufrufe gespeicherter Prozeduren usw. zu verzichten, um Leistung, Einfachheit oder beides zu erreichen.
Gordon Hartley

10

Alle Fremdschlüsseleinschränkungen wurden aus einer Datenbank entfernt, da sonst so viele Fehler auftreten würden.


8

Das passt nicht genau zu der Frage, aber ich werde es trotzdem als warnende Geschichte erwähnen. Ich arbeitete an einer verteilten App, die langsam lief, und flog nach DC, um an einem Meeting teilzunehmen, das in erster Linie auf die Lösung des Problems abzielte. Der Projektleiter begann, eine Neuarchitektur zu skizzieren, um die Verzögerung zu beheben. Ich meldete mich freiwillig, dass ich am Wochenende einige Messungen vorgenommen hatte, die den Engpass auf eine einzige Methode isolierten. Es stellte sich heraus, dass bei einer lokalen Suche ein Datensatz fehlte, sodass die Anwendung bei jeder Transaktion zu einem Remote-Server wechseln musste. Durch Hinzufügen des Datensatzes zum lokalen Speicher wurde die Verzögerung beseitigt - Problem gelöst. Beachten Sie, dass die Neuarchitektur das Problem nicht behoben hätte.


8

Überprüfen Sie vor JEDER Javascript-Operation, ob das Objekt, mit dem Sie arbeiten, vorhanden ist.

if (myObj) { //or its evil cousin, if (myObj != null) {
    label.text = myObj.value; 
    // we know label exists because it has already been 
    // checked in a big if block somewhere at the top
}

Mein Problem mit dieser Art von Code ist, dass es niemanden zu interessieren scheint, was passiert, wenn er nicht existiert? Einfach nichts tun? Geben Sie dem Benutzer kein Feedback?

Ich bin damit einverstanden, dass die Object expectedFehler ärgerlich sind, aber dies ist nicht die beste Lösung dafür.


Was ist dann die beste Lösung? Ich denke, es ist schlampig, Code zu schreiben, bei dem gelegentlich Fehler auftreten, auch wenn sie keine direkten Konsequenzen haben. Natürlich sollten Sie es nicht tun, wenn Sie unter keinen Umständen erwarten, dass das Objekt null ist - vielleicht haben Sie das so gemeint.
Simon

7

Wie wäre es mit YAGNI Extremismus. Es ist eine Form der vorzeitigen Pessimisierung. Es scheint, als ob Sie YAGNI jedes Mal, wenn Sie es anwenden, benötigen, was zu einem 10-fachen Aufwand beim Hinzufügen führt, als wenn Sie es am Anfang hinzugefügt hätten. Wenn Sie ein erfolgreiches Programm erstellen, werden Sie es wahrscheinlich brauchen. Wenn Sie es gewohnt sind, Programme zu erstellen, deren Leben schnell abläuft, dann üben Sie weiterhin YAGNI, denn dann nehme ich an, YAGNI.


3
Vielen Dank, ich habe diese lahmen Akronyme für extreme Programmierung satt und wie die Leute sie verwenden, um faule, kontraproduktive Praktiken zu unterstützen.
JAL

Studien von tatsächlichen Projekten zeigen, dass der tatsächliche Faktor zwischen einmaligem und wiederverwendbarem Code im Durchschnitt bei etwa 3 liegt. 10 ist also nur der "gefühlte" Wert, aber Sie haben absichtlich Recht.
Peterchen

@peterchen - sagen Sie, dass Studien zeigen, dass das Schreiben von wiederverwendbarem Code dreimal so lange dauert wie einmaliger Code, oder dass das Konvertieren von einmaligem Code in wiederverwendbaren Code dreimal so lange dauert wie das Schreiben der wiederverwendbare Code überhaupt?
Jeff Sternal

@jeff: IIRC verglichen sie ein Komplexitätsmaß (was auch immer Sie von ihnen halten) von Inline-Snippets, die in separate Methoden verschoben wurden. Die Komplexität steigt aufgrund zusätzlicher unterstützter Fälle, Parameterprüfung usw. (was mich davon ausgehen lässt, dass die Methoden eher klein waren). Lassen Sie mich versuchen, eine Referenz auszugraben.
Peterchen

6

Nicht gerade vorzeitige Optimierung - aber sicherlich falsch - wurde auf der BBC-Website aus einem Artikel über Windows 7 gelesen.

Herr Curran sagte, dass das Microsoft Windows-Team alle Aspekte des Betriebssystems überprüft habe, um Verbesserungen vorzunehmen. "Wir konnten die Abschaltzeit um 400 Millisekunden verkürzen, indem wir die Musik zum Herunterfahren der WAV-Datei leicht beschnitten haben.

Jetzt habe ich Windows 7 noch nicht ausprobiert, daher kann ich mich irren, aber ich bin bereit zu wetten, dass es andere Probleme gibt, die wichtiger sind als die Zeit, die zum Herunterfahren benötigt wird. Wenn ich die Meldung "Windows herunterfahren" sehe, wird der Monitor ausgeschaltet und ich gehe weg - wie profitieren mich diese 400 Millisekunden?


Sie werden wahrscheinlich feststellen, dass die anderen Probleme Nicht-Programmierern auf einer BBC-Website nicht so einfach zu erklären sind.
Tom Leys

Nun, das ist ein Winkel, den ich nicht berücksichtigt habe - vielleicht fange ich an, meinen Zynismus zu verlieren :-)
Belugabob

Diese 400 ms sind 400 ms Leistungsaufnahme. Wahrscheinlich unbedeutend, aber vielleicht summiert es sich im Laufe der Zeit. Trotzdem nichts, worüber ich mir Sorgen machen würde.
ZachS

1
Insgesamt habe ich viele Stunden verloren, bis XP-VMs heruntergefahren wurden, damit ich mit dem nächsten Schritt fortfahren kann. Ich bin sehr dankbar für ein schnelleres Herunterfahren.
James

1
Interessanterweise werden die WAV-Dateien asynchron wiedergegeben. Solange die Fanfare zum Herunterfahren kürzer ist als die zum Herunterfahren erforderliche Zeit, führt das Trimmen der WAV-Datei zu nichts. Und noch interessanter: Wenn sie das Herunterfahren so sehr optimiert haben, wie kommt es dann, dass jede Windows-Box, die ich herunterfahre, Äonen braucht, bis sie wirklich heruntergefahren ist? (Außer natürlich mit dem großen roten Knopf.)
TheBlastOne

6

Jemand in meiner Abteilung hat einmal eine String-Klasse geschrieben. Eine Schnittstelle wieCString , aber ohne die Windows-Abhängigkeit.

Eine "Optimierung", die sie machten, war zu nicht mehr Speicher als nötig zuzuweisen. Anscheinend nicht erkannt, dass Klassen wie std::stringüberschüssigen Speicher zuweisen, ist, dass eine Folge von +=Operationen in O (n) Zeit ausgeführt werden kann.

Stattdessen erzwang jeder einzelne +=Aufruf eine Neuzuweisung, die wiederholte Anhänge in einen O (n²) Schlemiel the Painter-Algorithmus verwandelte .


5

Ein ehemaliger Mitarbeiter von mir ( eigentlich ein Soab ) wurde beauftragt, ein neues Modul für unser Java-ERP zu erstellen, das Kundendaten hätte sammeln und analysieren sollen (Einzelhandel). Er beschloss, JEDES Kalender- / Datums- / Uhrzeitfeld in seine Komponenten (Sekunden, Minuten, Stunden, Tag, Monat, Jahr, Wochentag, Bimester, Trimester (!)) Aufzuteilen, weil "wie sonst würde ich nach 'jedem Montag' fragen?"


3
Das ist keine vorzeitige Optimierung, er dachte, er müsse das aus
Gründen der

Sicher, er dachte, er brauche das, aber da die meisten DBMS eine Art DAYOFWEEK-Funktion (Zeitstempel) haben, ist es meiner Meinung nach verfrüht genug, dieses Durcheinander im Voraus zu tun :)
Joril

1
Ich würde es nicht für OLTP verwenden, aber wenn Sie "Kundendaten analysieren", ist dies tatsächlich eine sehr flexible Methode zum Entwerfen eines Data Warehouse (solange Datum und Uhrzeit in verschiedene Dimensionen aufgeteilt sind). Möchten Sie DAYOFWEEK () wirklich für Millionen von Datenzeilen aufrufen oder nur eine Indexsuche für ein ganzzahliges Feld durchführen?
Tim Medora

Nun, ich weiß nicht, ob es so viele Zeilen gab, aber das ist sicherlich nicht die Erklärung, die gegeben wurde :)
Joril

3

Keine Beleidigung für irgendjemanden, aber ich habe gerade eine Aufgabe (Java) bewertet, die dies hatte

import java.lang.*;

1
Ich denke, Sie müssen diese Schülerin ein wenig locker machen, es sei denn, Sie haben ihr genug beigebracht, um zu wissen, warum dies keine gute Idee ist.
Bryan Oakley

24
Werde ich der einzige sein, der die Ironie eines Lehrers bemerkt, der WTF im Code eines Schülers anruft, der für den Unterricht verantwortlich ist, um richtig zu programmieren?
JohnFx

3
Ja, ich kann nicht sehen, dass das wehtun würde. Im schlimmsten Fall ist es überflüssig. Die Schüler tendieren dazu, während des Lernens auf starre Konsistenz zurückzugreifen, und das Importieren von java.lang stimmt streng mit dem überein, was der Schüler über das Importieren gelernt hat.
Cygil

1
Ich danke Ihnen allen, dass Sie mir das Offensichtliche erzählt haben. Es war eine Aufgabe der Computational Biology und ich habe sie weder gezählt noch erwähnt.
Überflogen am

2
@ JohnFX: Der Grader und der Lehrer sind nicht immer die gleiche Person.
Eddie
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.