Wie Knuth sagte,
Wir sollten kleine Wirkungsgrade vergessen, etwa in 97% der Fälle: Vorzeitige Optimierung ist die Wurzel allen Übels.
Dies ist etwas, was häufig in Stack Overflow-Antworten auf Fragen wie "Welcher ist der effizienteste Schleifenmechanismus", "SQL-Optimierungstechniken?" ( und so weiter ). Die Standardantwort auf diese Fragen zu Optimierungstipps besteht darin, Ihren Code zu profilieren und zu prüfen, ob es sich zuerst um ein Problem handelt. Wenn dies nicht der Fall ist, ist Ihre neue Technik nicht erforderlich.
Meine Frage ist, ob eine bestimmte Technik anders, aber nicht besonders dunkel oder verschleiert ist, kann dies wirklich als vorzeitige Optimierung angesehen werden?
Hier ist ein verwandter Artikel von Randall Hyde mit dem Titel The Fallacy of Premature Optimization .
Antworten:
Don Knuth startete die literarische Programmierbewegung , weil er glaubte, dass die wichtigste Funktion des Computercodes darin besteht, die Absicht des Programmierers einem menschlichen Leser mitzuteilen . Jede Codierungspraxis, die es schwieriger macht, Ihren Code im Namen der Leistung zu verstehen, ist eine vorzeitige Optimierung.
Bestimmte Redewendungen, die im Namen der Optimierung eingeführt wurden, sind so populär geworden, dass jeder sie versteht und erwartet und nicht verfrüht wird. Beispiele beinhalten
Verwenden der Zeigerarithmetik anstelle der Array-Notation in C, einschließlich der Verwendung von Redewendungen wie
Globale Variablen an lokale Variablen in Lua neu binden, wie in
Nehmen Sie über solche Redewendungen hinaus Abkürzungen auf eigene Gefahr .
Alle Optimierungen sind verfrüht, es sei denn
Ein Programm ist zu langsam (viele Leute vergessen diesen Teil).
Sie haben eine Messung (Profil oder ähnliches), die zeigt, dass die Optimierung die Dinge verbessern könnte .
(Es ist auch zulässig, den Speicher zu optimieren.)
Direkte Antwort auf Frage:
BEARBEITEN : Als Reaktion auf Kommentare ist die Verwendung von Quicksort anstelle eines einfacheren Algorithmus wie der Einfügesortierung ein weiteres Beispiel für eine Redewendung, die jeder versteht und erwartet . (Wenn Sie jedoch Ihre eigene Sortierroutine schreiben, anstatt die Bibliothekssortierroutine zu verwenden, hoffen Sie, dass Sie einen sehr guten Grund haben.)
quelle
Meiner Meinung nach sollten 90% Ihrer Optimierung in der Entwurfsphase erfolgen, basierend auf den wahrgenommenen aktuellen und vor allem zukünftigen Anforderungen. Wenn Sie einen Profiler herausnehmen müssen, weil Ihre Anwendung nicht auf die erforderliche Last skaliert werden kann, haben Sie ihn zu spät verlassen, und IMO wird viel Zeit und Mühe verschwenden, während das Problem nicht behoben werden kann.
In der Regel sind nur Optimierungen sinnvoll, mit denen Sie eine Leistungsverbesserung um eine Größenordnung in Bezug auf die Geschwindigkeit oder einen Multiplikator in Bezug auf Speicher oder Bandbreite erzielen. Diese Arten von Optimierungen beziehen sich normalerweise auf die Auswahl des Algorithmus und die Speicherstrategie und sind äußerst schwierig in vorhandenen Code umzukehren. Sie können so tief gehen, dass sie die Entscheidung über die Sprache beeinflussen, in der Sie Ihr System implementieren.
Also mein Rat, optimieren Sie frühzeitig, basierend auf Ihren Anforderungen, nicht Ihrem Code, und achten Sie auf die mögliche längere Lebensdauer Ihrer App.
quelle
while (s[0]==' ') s = s.substring(1)
for(i=0; i<s.len && s[i]==' '; ++i); s=s.substring(i)
--- aber das erfordert schon zu wissen , potenzielle Leistungsprobleme (Profilometer sind wertvolle Werkzeuge für ständiges Lernen hier).Wenn Sie kein Profil erstellt haben, ist es verfrüht.
quelle
Ähm ... Sie haben also zwei Techniken zur Hand, die hinsichtlich der Kosten identisch sind (gleicher Aufwand beim Verwenden, Lesen, Ändern) und eine effizienter ist. Nein, die effizientere zu verwenden wäre in diesem Fall nicht verfrüht.
Wenn Sie das Schreiben von Code unterbrechen, um nach Alternativen zu gängigen Programmierkonstrukten / Bibliotheksroutinen zu suchen, besteht die Möglichkeit, dass irgendwo eine effizientere Version herumhängt, obwohl die relative Geschwindigkeit des Schreibens nach allem, was Sie wissen, eigentlich keine Rolle spielt. .. Das ist verfrüht.
quelle
Hier ist das Problem, das ich mit dem gesamten Konzept der Vermeidung vorzeitiger Optimierung sehe.
Es gibt eine Trennung zwischen dem Sagen und dem Tun.
Ich habe viele Leistungsoptimierungen vorgenommen und große Faktoren aus ansonsten gut gestaltetem Code herausgepresst, scheinbar ohne vorzeitige Optimierung. Hier ist ein Beispiel.
In fast allen Fällen ist der Grund für die suboptimale Leistung das, was ich als galoppierende Allgemeinheit bezeichne. Dies ist die Verwendung abstrakter mehrschichtiger Klassen und eines gründlichen objektorientierten Designs, bei dem einfache Konzepte weniger elegant, aber völlig ausreichend wären .
Und in dem Lehrmaterial, in dem diese abstrakten Designkonzepte vermittelt werden, wie z. B. benachrichtigungsgesteuerte Architektur und Verstecken von Informationen, in denen das einfache Festlegen einer booleschen Eigenschaft eines Objekts einen unbegrenzten Welleneffekt von Aktivitäten haben kann, was ist der angegebene Grund? Effizienz .
War das eine vorzeitige Optimierung oder nicht?
quelle
Lassen Sie zuerst den Code funktionieren. Zweitens überprüfen Sie, ob der Code korrekt ist. Drittens machen Sie es schnell.
Jeder Code Änderung , die vor der Bühne # getan wird 3 ist auf jeden Fall verfrüht. Ich bin mir nicht ganz sicher, wie ich die zuvor getroffenen Entwurfsentscheidungen klassifizieren soll (wie die Verwendung gut geeigneter Datenstrukturen), aber ich bevorzuge die Verwendung von Abstraktionen, mit denen man einfach programmieren kann, anstatt mit denen, die eine gute Leistung erbringen, bis ich bei bin Eine Phase, in der ich mit der Profilerstellung beginnen kann und eine korrekte (wenn auch häufig langsame) Referenzimplementierung zum Vergleichen der Ergebnisse habe.
quelle
Sie sprechen anscheinend von einer Optimierung wie der Verwendung eines Hash-basierten Suchcontainers im Vergleich zu einem indizierten Container wie einem Array, wenn viele wichtige Suchvorgänge durchgeführt werden. Dies ist keine vorzeitige Optimierung, sondern etwas, das Sie in der Entwurfsphase entscheiden sollten.
Die Art der Optimierung, um die es in der Knuth-Regel geht, besteht darin, die Länge der am häufigsten verwendeten Codepfade zu minimieren, den Code zu optimieren, der am häufigsten ausgeführt wird, indem beispielsweise in der Assembly neu geschrieben oder der Code vereinfacht wird, wodurch er weniger allgemein wird. Dies hat jedoch keinen Sinn, bis Sie sicher sind, welche Teile des Codes diese Art der Optimierung benötigen, und die Optimierung wird (könnte?) Das Verständnis oder die Wartung des Codes erschweren. Daher ist "vorzeitige Optimierung die Wurzel allen Übels".
Knuth sagt auch, dass es immer besser ist, anstatt zu optimieren, die von Ihrem Programm verwendeten Algorithmen und die Herangehensweise an ein Problem zu ändern. Während durch eine kleine Optimierung die Geschwindigkeit durch Optimierung um 10% gesteigert werden kann, kann eine grundlegende Änderung der Funktionsweise Ihres Programms zu einer 10-fachen Geschwindigkeit führen.
Als Reaktion auf viele andere Kommentare zu dieser Frage: Algorithmusauswahl! = Optimierung
quelle
Aus Datenbanksicht ist es bestenfalls tollkühn, in der Entwurfsphase kein optimales Design zu berücksichtigen. Datenbanken lassen sich nicht einfach umgestalten. Sobald sie schlecht entworfen sind (dies ist ein Design, das die Optimierung nicht berücksichtigt, egal wie Sie versuchen, sich hinter dem Unsinn der vorzeitigen Optimierung zu verstecken), kann es fast nie wiederhergestellt werden, da die Datenbank zu grundlegend für das ist Betrieb des gesamten Systems. Es ist weitaus kostengünstiger, unter Berücksichtigung des optimalen Codes für die von Ihnen erwartete Situation korrekt zu entwerfen, als zu warten, bis eine Million Benutzer vorhanden sind und die Leute schreien, weil Sie in der gesamten Anwendung Cursor verwendet haben. Andere Optimierungen wie die Verwendung von sargeable Code, die Auswahl der bestmöglichen Indizes usw. sind nur zur Entwurfszeit sinnvoll. Es gibt einen Grund, warum schnell und schmutzig so genannt wird. Da es nie gut funktionieren kann, sollten Sie die Schnelligkeit nicht als Ersatz für guten Code verwenden. Wenn Sie die Leistungsoptimierung in Datenbanken verstehen, können Sie auch Code schreiben, der mit größerer Wahrscheinlichkeit zur gleichen Zeit oder weniger gut funktioniert als das Schreiben von Code, der nicht gut funktioniert. Sich nicht die Zeit zu nehmen, um zu lernen, was ein leistungsfähiges Datenbankdesign ist, ist Entwicklerfaulheit, keine bewährte Methode.
quelle
Der Punkt der Maxime ist, dass die Optimierung typischerweise kompliziert und komplex ist. In der Regel benötigen Sie als Architekt / Designer / Programmierer / Betreuer klaren und präzisen Code, um zu verstehen, was vor sich geht.
Wenn eine bestimmte Optimierung klar und präzise ist, können Sie gerne damit experimentieren (gehen Sie jedoch zurück und prüfen Sie, ob diese Optimierung wirksam ist). Es geht darum, den Code während des gesamten Entwicklungsprozesses klar und präzise zu halten, bis die Vorteile der Leistung die Kosten für das Schreiben und Verwalten der Optimierungen überwiegen.
quelle
Ich versuche nur zu optimieren, wenn ein Leistungsproblem bestätigt wird.
Meine Definition der vorzeitigen Optimierung lautet "Aufwand für Code, von dem nicht bekannt ist, dass er ein Leistungsproblem darstellt". Es gibt definitiv einen Zeitpunkt und einen Ort für die Optimierung. Der Trick besteht jedoch darin, die zusätzlichen Kosten nur dort auszugeben, wo sie für die Leistung der Anwendung von Bedeutung sind und wo die zusätzlichen Kosten den Leistungseinbruch überwiegen.
Beim Schreiben von Code (oder einer DB-Abfrage) bemühe ich mich, "effizienten" Code zu schreiben (dh Code, der seine beabsichtigte Funktion schnell und vollständig mit der einfachsten vernünftigen Logik ausführt). Beachten Sie, dass "effizienter" Code nicht unbedingt mit "optimiert" identisch ist. Code. Optimierungen führen häufig zu einer zusätzlichen Komplexität des Codes, was sowohl die Entwicklungs- als auch die Wartungskosten dieses Codes erhöht.
Mein Rat: Versuchen Sie, die Kosten für die Optimierung nur dann zu bezahlen, wenn Sie den Nutzen quantifizieren können.
quelle
Bei der Programmierung sind eine Reihe von Parametern von entscheidender Bedeutung. Unter diesen sind:
Die Optimierung (auf Leistung ausgerichtet) geht häufig zu Lasten anderer Parameter und muss gegen den "Verlust" in diesen Bereichen abgewogen werden.
Wenn Sie die Möglichkeit haben, bekannte Algorithmen auszuwählen, die eine gute Leistung erbringen, sind die Kosten für die "Optimierung" im Voraus oft akzeptabel.
quelle
Die Optimierung kann auf verschiedenen Granularitätsstufen erfolgen, von sehr hohen bis zu sehr niedrigen Ebenen:
Beginnen Sie mit einer guten Architektur, loser Kopplung, Modularität usw.
Wählen Sie die richtigen Datenstrukturen und Algorithmen für das Problem.
Optimieren Sie den Speicher und versuchen Sie, mehr Code / Daten in den Cache einzufügen. Das Speichersubsystem ist 10 bis 100 Mal langsamer als die CPU. Wenn Ihre Daten auf die Festplatte ausgelagert werden, ist es 1000 bis 10.000 Mal langsamer. Vorsicht beim Speicherverbrauch führt eher zu größeren Vorteilen als zur Optimierung einzelner Anweisungen.
Verwenden Sie in jeder Funktion die Anweisungen zur Flusskontrolle in geeigneter Weise. (Verschieben Sie unveränderliche Ausdrücke außerhalb des Schleifenkörpers. Setzen Sie den häufigsten Wert in einem Schalter / Fall usw. an die erste Stelle.)
Verwenden Sie in jeder Anweisung die effizientesten Ausdrücke, um das richtige Ergebnis zu erzielen. (Multiplizieren vs. Verschieben usw.)
Es ist nicht unbedingt notwendig , zu entscheiden, ob ein Divide-Ausdruck oder ein Shift-Ausdruck verwendet werden soll vorzeitige Optimierung. Es ist nur verfrüht, wenn Sie dies tun, ohne zuvor die Architektur, Datenstrukturen, Algorithmen, den Speicherbedarf und die Flusskontrolle zu optimieren.
Und natürlich ist jede Optimierung verfrüht, wenn Sie keinen Zielleistungsschwellenwert definieren.
In den meisten Fällen entweder:
A) Sie können den Zielleistungsschwellenwert erreichen, indem Sie Optimierungen auf hoher Ebene durchführen. Es ist also nicht erforderlich, mit den Ausdrücken herumzuspielen.
oder
B) Selbst nachdem Sie alle möglichen Optimierungen durchgeführt haben, werden Sie Ihren Zielleistungsschwellenwert nicht erreichen, und die Optimierungen auf niedriger Ebene machen keinen ausreichenden Leistungsunterschied, um den Verlust der Lesbarkeit zu rechtfertigen.
Nach meiner Erfahrung können die meisten Optimierungsprobleme entweder auf der Ebene der Architektur / des Designs oder der Datenstruktur / des Algorithmus gelöst werden. Die Optimierung des Speicherbedarfs ist häufig (wenn auch nicht immer) erforderlich. Es ist jedoch selten erforderlich, die Flusssteuerungs- und Ausdruckslogik zu optimieren. Und in den Fällen, in denen es tatsächlich notwendig ist, reicht es selten aus.
quelle
Die Notwendigkeit, einen Profiler zu verwenden, sollte in extremen Fällen bestehen bleiben. Die Ingenieure des Projekts sollten wissen, wo Leistungsengpässe liegen.
Ich denke, "vorzeitige Optimierung" ist unglaublich subjektiv.
Wenn ich Code schreibe und ich weiß dass ich eine Hashtabelle verwenden sollte, werde ich das tun. Ich werde es nicht fehlerhaft implementieren und dann warten, bis der Fehlerbericht einen Monat oder ein Jahr später eintrifft, wenn jemand ein Problem damit hat.
Redesign ist teurer als die Optimierung eines Designs auf offensichtliche Weise von Anfang an.
Natürlich werden einige kleine Dinge beim ersten Mal übersehen, aber dies sind selten wichtige Designentscheidungen.
Deshalb: Ein Design NICHT zu optimieren ist IMO ein Code-Geruch an und für sich.
quelle
Normans Antwort ist ausgezeichnet. Irgendwie führen Sie routinemäßig eine "vorzeitige Optimierung" durch, die eigentlich Best Practices sind, da bekannt ist, dass eine andere Vorgehensweise völlig ineffizient ist.
Zum Beispiel, um zu Normans Liste hinzuzufügen:
for (i = 0; i < strlen(str); i++)
folgt zu schleifen: (da strlen hier ein Funktionsaufruf ist, der jedes Mal durch den String läuft und in jeder Schleife aufgerufen wird);for (i = 0 l = str.length; i < l; i++)
und es ist immer noch lesbar, also OK.Und so weiter. Solche Mikrooptimierungen sollten jedoch niemals auf Kosten der Lesbarkeit von Code gehen.
quelle
Es ist erwähnenswert, dass Knuths ursprüngliches Zitat aus einem Artikel stammt, den er verfasst hat, um die Verwendung
goto
in sorgfältig ausgewählten und gemessenen Bereichen zu fördern , um Hotspots zu beseitigen. Sein Zitat war eine Einschränkung, die er hinzufügte, um seine Gründe für diegoto
Beschleunigung dieser kritischen Schleifen zu rechtfertigen .Und weiter:
Denken Sie daran, wie er in Anführungszeichen "optimiert" verwendet hat (die Software ist wahrscheinlich nicht wirklich effizient). Beachten Sie auch, dass er nicht nur diese "Pennywise-and-Pound-Dummkopf" -Programmierer kritisiert, sondern auch die Leute, die darauf reagieren, indem sie vorschlagen, dass Sie kleine Ineffizienzen immer ignorieren sollten. Zum abschließenden Teil:
... und noch etwas mehr über die Bedeutung von Profiling-Tools:
Die Leute haben sein Zitat überall missbraucht und oft darauf hingewiesen, dass Mikrooptimierungen verfrüht sind, als sein gesamtes Papier Mikrooptimierungen befürwortete! Eine der von ihm kritisierten Personengruppen, die diese "konventionelle Weisheit" wiederholen, weil er die Effizienz im Kleinen immer ignoriert, missbraucht häufig sein Zitat, das ursprünglich teilweise gegen solche Typen gerichtet war, die alle Formen der Mikrooptimierung abschrecken .
Es war jedoch ein Zitat zugunsten angemessen angewandter Mikrooptimierungen, wenn diese von einer erfahrenen Hand mit einem Profiler verwendet wurden. Das heutige analoge Äquivalent könnte lauten: "Menschen sollten bei der Optimierung ihrer Software keine blinden Stiche machen, aber benutzerdefinierte Speicherzuordnungen können einen großen Unterschied machen, wenn sie in Schlüsselbereichen angewendet werden, um die Referenzlokalität zu verbessern" oder " Handgeschriebener SIMD-Code mit einem SoA rep ist wirklich schwer zu pflegen und sollte nicht überall verwendet werden, aber es kann viel schneller Speicher verbrauchen, wenn es von einer erfahrenen und geführten Hand angemessen angewendet wird. "
Jedes Mal, wenn Sie versuchen, sorgfältig angewandte Mikrooptimierungen zu fördern, wie Knuth es oben beworben hat, ist es gut, einen Haftungsausschluss einzufügen, um Neulinge davon abzuhalten, zu aufgeregt zu werden und blindlings Optimierungen vorzunehmen, z. B. ihre gesamte Software für die Verwendung neu zu schreiben
goto
. Das war zum Teil das, was er tat. Sein Zitat war praktisch Teil eines großen Haftungsausschlusses, genau wie jemand, der ein Motorrad über eine brennende Feuerstelle springt, einen Haftungsausschluss hinzufügen könnte, dass Amateure dies nicht zu Hause versuchen sollten, während sie gleichzeitig diejenigen kritisieren, die es ohne angemessenes Wissen und Ausrüstung versuchen und verletzt werden .Was er als "vorzeitige Optimierungen" ansah, waren Optimierungen, die von Leuten angewendet wurden, die effektiv nicht wussten, was sie taten: Sie wussten nicht, ob die Optimierung wirklich benötigt wurde, maßen nicht mit geeigneten Werkzeugen, verstanden vielleicht nicht die Natur von Ihre Compiler- oder Computerarchitektur und vor allem ihre "Pennywise-and-Pound-Dummheit" waren, was bedeutete, dass sie die großen Möglichkeiten zur Optimierung (Einsparung von Millionen von Dollar) übersehen, indem sie versuchten, ein paar Cent zu kneifen, und während sie Code erstellten, den sie nicht können länger effektiv debuggen und warten.
Wenn Sie nicht in die Kategorie "Pennywise-and-Pound-Dummkopf" passen, optimieren Sie nicht vorzeitig nach Knuths Maßstäben, selbst wenn Sie a
goto
verwenden, um eine kritische Schleife zu beschleunigen (was unwahrscheinlich ist) um viel gegen die heutigen Optimierer zu helfen, aber wenn es so wäre und in einem wirklich kritischen Bereich, dann würden Sie nicht vorzeitig optimieren). Wenn Sie tatsächlich alles anwenden, was Sie in Bereichen tun, die wirklich gebraucht werden und von denen sie wirklich profitieren, dann sind Sie in den Augen von Knuth einfach großartig.quelle
Vorzeitige Optimierung bedeutet für mich, die Effizienz Ihres Codes zu verbessern, bevor Sie ein funktionierendes System haben und bevor Sie es tatsächlich profiliert haben und wissen, wo der Engpass liegt. Auch danach sollten in vielen Fällen Lesbarkeit und Wartbarkeit vor der Optimierung liegen.
quelle
Ich denke nicht, dass anerkannte Best Practices vorzeitige Optimierungen sind. Es geht mehr um die Brenndauer der Was-wäre-wenn-Fälle, bei denen es sich je nach Nutzungsszenario um potenzielle Leistungsprobleme handelt. Ein gutes Beispiel: Wenn Sie eine Woche lang versuchen, die Reflexion über ein Objekt zu optimieren, bevor Sie den Beweis haben, dass es sich um einen Engpass handelt, optimieren Sie vorzeitig.
quelle
Wenn Sie nicht feststellen, dass Ihre Anwendung aufgrund eines Benutzer- oder Geschäftsbedarfs mehr Leistung benötigt, gibt es wenig Grund zur Sorge um die Optimierung. Tun Sie auch dann nichts, bis Sie Ihren Code profiliert haben. Greife dann die Teile an, die am meisten Zeit in Anspruch nehmen.
quelle
So wie ich das sehe, ist es eine vorzeitige Optimierung, wenn Sie etwas optimieren, ohne zu wissen, wie viel Leistung Sie in verschiedenen Szenarien erzielen können. Das Ziel von Code sollte es dem Menschen wirklich leichter machen, ihn zu lesen.
quelle
Wie ich zu einer ähnlichen Frage geschrieben habe, gelten folgende Optimierungsregeln:
1) Nicht optimieren
2) (nur für Experten) Später optimieren
Wann ist die Optimierung verfrüht? Normalerweise.
Die Ausnahme liegt möglicherweise in Ihrem Design oder in gut gekapseltem Code, der häufig verwendet wird. In der Vergangenheit habe ich an zeitkritischem Code (einer RSA-Implementierung) gearbeitet, bei dem der vom Compiler erstellte Assembler und das Entfernen eines einzelnen unnötigen Befehls in einer inneren Schleife eine 30% ige Beschleunigung ergab. Die Beschleunigung durch die Verwendung komplexerer Algorithmen war jedoch um Größenordnungen höher.
Eine andere Frage, die Sie sich bei der Optimierung stellen sollten, lautet: "Mache ich hier das Äquivalent zur Optimierung für ein 300-Baud-Modem?" . Mit anderen Worten, wird Moores Gesetz Ihre Optimierung in Kürze irrelevant machen. Viele Skalierungsprobleme können gelöst werden, indem mehr Hardware auf das Problem geworfen wird.
Last but not least ist es verfrüht zu optimieren, bevor das Programm zu langsam läuft. Wenn es sich um eine Webanwendung handelt, über die Sie sprechen, können Sie sie unter Last ausführen, um festzustellen, wo die Engpässe liegen. Es ist jedoch wahrscheinlich, dass Sie dieselben Skalierungsprobleme wie die meisten anderen Websites haben und dieselben Lösungen gelten.
edit: Übrigens würde ich in Bezug auf den verlinkten Artikel viele der getroffenen Annahmen in Frage stellen. Erstens ist es nicht wahr, dass Moores Gesetz in den 90er Jahren aufgehört hat zu arbeiten. Zweitens ist es nicht offensichtlich, dass die Zeit des Benutzers wertvoller ist als die Zeit des Programmierers. Die meisten Benutzer nutzen (gelinde gesagt) nicht jeden verfügbaren CPU-Zyklus, sondern warten wahrscheinlich darauf, dass das Netzwerk etwas unternimmt. Außerdem entstehen Opportunitätskosten, wenn die Zeit des Programmierers von der Implementierung von etwas anderem abgelenkt wird, um ein paar Millisekunden von etwas zu sparen, das das Programm tut, während der Benutzer am Telefon ist. Alles, was länger ist, ist normalerweise keine Optimierung, sondern eine Fehlerbehebung.
quelle