Ich habe in einem Artikel Folgendes gesehen:
Entwickler lieben es, Code aus gutem Grund zu optimieren. Es ist so befriedigend und macht Spaß. Es ist jedoch weitaus wichtiger zu wissen, wann optimiert werden muss. Leider haben Entwickler im Allgemeinen eine schreckliche Vorstellung davon, wo die Leistungsprobleme in einer Anwendung tatsächlich liegen werden.
Wie kann ein Entwickler diese schlechte Intuition vermeiden? Gibt es gute Tools, um herauszufinden, welche Teile Ihres Codes wirklich optimiert werden müssen (für Java)? Kennen Sie einige Artikel, Tipps oder gute Lektüre zu diesem Thema?
java
performance
Mona
quelle
quelle
Antworten:
Im Wesentlichen müssen Sie anderen beweisen können, wo das Problem lag, und dass diese Änderung dazu geführt hat, dass es nicht mehr besteht.
Nicht in der Lage zu beweisen , eine Verbesserung, qualifiziert - in meiner persönlichen Meinung - zum sofortigen Zurückkehren zu der ursprünglichen Version.
quelle
Die einzige Möglichkeit zu wissen, wo optimiert werden muss, besteht darin, einen Code zu erstellen. Anstatt Änderungen vorzunehmen, von denen Sie glauben, dass sie von Vorteil sind, sollten Sie genau wissen, wo sich der Code mit der schlechtesten Leistung befindet, und dort beginnen.
Java macht dies mit dem VisualVM-Tool , das mit den neuesten Versionen des Java Development Kit (JDK) gebündelt wurde, ziemlich einfach . Die Idee ist herauszufinden, welche Methoden am häufigsten aufgerufen werden und mit welchen Methoden Sie die meiste Zeit verbringen, sowohl in Ihrem Code als auch in externen Bibliotheken. Sie können auch Leistungsdaten zur Garbage Collection abrufen, um den Collector zu optimieren und den für Ihre Anwendung erforderlichen minimalen / maximalen Heap-Speicherplatz anzupassen.
quelle
Da hier von Profilern die Rede ist, werde ich mich auf diesen Teil der Frage konzentrieren.
Du. machen. nicht. Stattdessen optimieren Sie nie früh .
Wiederholen Sie es immer und immer wieder, da es ein religiöses Mantra ist.
Sie werden feststellen, dass Sie das tun und entdecken, dass Sie es nicht hätten tun sollen.
Und dann nochmal.
Und wieder.
Frühe Optimierung ist eine der Programmierer Todsünden .
Werkzeuge und Sachen sind Teil der späteren Optimierung, die ein etabliertes Handwerk ist .
quelle
Diese Tools werden als Profiler bezeichnet . Sie können sie verwenden, um tatsächlich zu messen, welche Teile Ihres Programms die meiste Zeit für die Ausführung benötigen, sodass Sie sich auf Ihre Optimierungsbemühungen konzentrieren können.
Ebenso wichtig ist es, nach den Änderungen erneut zu messen , um sicherzustellen, dass Ihre Änderungen die beabsichtigte Wirkung haben.
quelle
Sehen Sie sich auch an, wie viel Speicher Ihr Programm belegt, nicht nur seine Geschwindigkeit oder Laufzeit.
Viele Programmierer, die mit Garbage-Collected-Sprachen wie Java arbeiten, haben fälschlicherweise den Eindruck, dass Garbage-Collection Speicherverluste verhindert. Das ist nicht der Fall. Wenn Sie einen Verweis auf ein Objekt haben, das Sie nicht mehr benötigen, wird er nicht gesammelt und läuft aus.
Ich habe Java-Webanwendungen gesehen, die so undicht waren, dass ihr Server keinen Swap-Speicher mehr hat!
Wenn Sie sowohl einen Laufzeitprofiler als auch eine Art Speicherprofiler verwenden, lernen Sie intuitiv, schnelleren und schlankeren Code zu schreiben. Dies hat zur Folge, dass Ihr Code beim ersten Versuch mit größerer Wahrscheinlichkeit schnell ausgeführt wird.
quelle
Meine Abhilfe besteht darin, zunächst klare Antworten auf zwei Fragen zu erhalten:
Gelernt oben Trick von Tiger Team Jungs , die einmal eingeladen wurden , ein gebrochenes Release unseres Produktes zu speichern. Das Release aus Performance - Gründen gebrochen war, konnte es Unternehmen lose strategischen Kunden , die gerechtfertigt machen Tiger Jungs Beteiligung (ziemlich teuer btw). Ich wurde beauftragt, sie bei der Klärung der Projektdetails zu unterstützen. Dies wurde auch als Gelegenheit genutzt, ein oder zwei Informationen über die Leistung zu erhalten.
quelle
Was ich gefunden habe, ist das beste Gegenmittel gegen vorzeitige Optimierung ist diese Methode .
Sobald Sie es verwendet haben, um Code zu beschleunigen (wie in diesem Beispiel ), wird es zu einer eigenen Sucht, und Sie verstehen, dass das erste Prinzip der Leistungsoptimierung nicht das Optimieren von Code ist, sondern das Problem .
Echte Optimierung ist zu frühzeitige Optimierung, wie die Jagd, um Ihre Familie zu ernähren, das Schießen von Blechdosen ist. Es geht nur darum, den Steinbruch zu finden.
quelle
Alte Frage, aber ich werde diese Antwort anbieten, die sich erheblich von den anderen unterscheidet.
Die großen Chancen für Leistungssteigerungen ergeben sich aus der Parallelverarbeitung. Versuchen Sie, Ihren Code so zu gestalten, dass er mehrere Threads nutzt. (Auch wenn Sie dies der Einfachheit halber in Version 1 nicht tun). Wenig Rätselraten oder Intuition notwendig.
Alles andere ist eine vorzeitige Optimierung und erfordert Ihre Intuition, die oft falsch ist.
quelle
Ihre Intuition kann sich mit der Zeit verbessern. Ich würde das rausschmeißen, vielleicht ein bisschen kontrovers, aber über viele Jahre mit VTune und CodeAnalyst und jetzt mit CodeXL würde ich sagen, dass ich in meinen Intuitionen viel genauer bin als vorher, wo die Hotspots zumindest sein werden Der Punkt, an dem ich nicht mehr völlig unvorbereitet bin, wenn ich Code profiliere. Das heißt nicht, dass ich versuche, Dinge blind zu optimieren.
Die Profilerstellung hat meine Abhängigkeit von Profilern erhöht, nicht verringert. Ich sage nur, ich kann leichter vorhersehen, wie die Profilerstellungsergebnisse in gewissem Maße aussehen werden, und außerdem Hotspots erfolgreich beseitigen und die Zeit verkürzen, die für den Abschluss des Benutzerendvorgangs erforderlich ist, ohne blinde Stiche im Dunkeln zu machen und zu vermissen (etwas, das Sie tun) kann dies auch tun, wenn Sie einen Profiler verwenden, bis Sie nicht nur verstehen, was die Hotspots sind, sondern auch, warum sie genau Hotspots in Bezug auf beispielsweise Cache-Fehler sind.
Erst als ich anfing, Profiler zu verwenden, begann ich, diese Intuition zu verbessern. Einer der Gründe dafür ist, dass Sie, wenn Sie mit Ihrem Code vertraut sind, möglicherweise die größten und offensichtlichsten Hotspots richtig einschätzen, aber nicht alle Feinheiten dazwischen. Natürlich, wenn Sie eine Benutzer-End-Operation haben, die eine Stunde in Anspruch nimmt und es einen lückenhaften quadratischen Komplexitätsalgorithmus gibt, der eine Eingabe mit einem Umfang von hunderttausend Elementen verarbeitet, können Sie wahrscheinlich Ihre gesamten Ersparnisse auf die Idee bringen, dass es sich um die quadratische Komplexität handelt Algorithmus hier schuld. Aber das gibt Ihnen keinen detaillierten Einblick oder lässt Sie beispielsweise genau wissen, was nicht zur Zeit beiträgt.
Es gibt so viel Wert, wenn Sie anfangen zu profilieren und zu sehen, wo all die Dinge, von denen Sie dachten, dass sie einen größeren Beitrag zur Zeit geleistet haben, nicht viel Zeit beigetragen haben. Nicht die offensichtlichen Ursachen für Ineffizienzen, sondern die, von denen Sie vermuteten, dass sie geringfügig ineffizient waren. Nach der Profilerstellung stellten Sie jedoch fest, dass sie zu keinem Zeitpunkt einen Beitrag geleistet haben. Und hier erhalten Sie möglicherweise die intuitivste Einsicht, wenn Sie feststellen, dass Sie in all den subtilen Bereichen, in denen es nicht offensichtlich ist, wie viel Zeit gerade aufgewendet wird, falsch dargestellt werden.
Die menschliche Intuition, die über die offensichtliche algorithmische Komplexität hinausgeht, beginnt häufig falsch, da die Effizienz der Maschine und die Effizienz des menschlichen Geistes sehr unterschiedlich sind. Anfangs ist es nicht so intuitiv, über Speicherhierarchien nachzudenken, die von den Registern über den CPU-Cache zum DRAM zur Festplatte gehen. Es ist nicht intuitiv zu denken, dass redundante Arithmetik möglicherweise schneller ist, als mehr Verzweigungs- oder Speicherzugriffe auf eine Nachschlagetabelle durchzuführen, um einige Verarbeitungsarbeiten zu überspringen. Wir neigen dazu, uns Gedanken darüber zu machen, wie viel Arbeit noch zu tun ist, während wir Dinge wie die Kosten für Entscheidungen und das Laden und Speichern von Speicher abrechnen. Was für die Hardware effizient ist, ist häufig in einer Weise sehr kontraintuitiv, die von Anfang an alle Ihre menschlichen Annahmen durchbricht.
Wo die Verbesserung dieser Intuition durch Profilerstellung helfen kann, ist das Interface-Design . Die Änderung des Schnittstellendesigns ist im Nachhinein sehr kostspielig. Die Kosten steigen proportional zur Anzahl der Stellen, die von dieser Schnittstelle abhängen. Wenn Sie anfangen, Ihre Intuition zu verbessern, können Sie beim ersten Mal besser mit dem Entwerfen von Benutzeroberflächen beginnen, sodass Raum für zukünftige Optimierungen bleibt, ohne kostspielige Änderungen am Design vornehmen zu müssen. Wieder ist diese Intuition etwas, das Sie im Allgemeinen entwickeln und das Sie unbegrenzt weiterentwickeln, indem Sie immer diesen Profiler zur Hand haben.
quelle
Profiler helfen dabei, die schlechte Intuition in Bezug auf Code zu korrigieren. Angesichts der heutigen Hardwareprognosen ist es nicht praktikabel, die Leistung Ihres Codes vorherzusagen, aber dies galt noch vor so vielen Jahrzehnten für Knuth, der sich dafür aussprach, Profiler als Teil der Standardtools für die Entwicklung zur Fehlerbehebung einzubeziehen "Pennywise-and-Pfund-Dummheit" Natur der Entwickler. Aber ich werde mit dieser Antwort einen ganz anderen Weg einschlagen, da die Antworten in anderer Hinsicht umfassend sind und das Verständnis der Benutzer das andere "Problem" ist.
Persönlich habe ich gesehen, wie ein besonders brillanter Entwickler (aber mit lückenhaften blinden Flecken, wie Benutzer die Software tatsächlich verwenden) einen Unterteilungsalgorithmus mit dem Profiler in der Hand optimiert (ein sehr guter, teurer und umfassender Algorithmus: Intels VTune mit Anrufdiagramm) Abtastung auf GPU-Profilern) für Netze erzielen erstaunliche Ergebnisse mit Milliarden von Facetten auf der GPU, wenn einfache Grundelemente wie Würfel mit 6 Käfig- / Eingabepolygonen unterteilt werden. Abgesehen davon, dass er es gegen diesen Testfall abgestimmt und abgestimmt hat, der mit keinem realen Anwendungsfall vergleichbar war (Benutzer möchten nicht, dass eine Milliarde Facetten zu einem unterteilten Würfel einer perfekten Kugel ähneln, sondern dass ihre Unterteilungseingaben in der Regel Zeichen und Fahrzeuge sind) und andere komplexe Eingaben).
Witzigerweise kam ich mit einem Gehirn, das halb so funktional war wie er, und ohne meine Promotion in meiner Karriere weiter, nur aus dem Grund, dass ich verstand, was Benutzer wollten, was Marketing wollten, was Designer wollten. Ich kann gar nicht genug betonen, wie nützlich es ist, sich in die Denkweise und das Verhalten der Benutzer hineinzuversetzen und sich Ihre Software und die Aufgaben anzusehen, die sie als tatsächliche Benutzer ausführen muss, während Sie sich von den von Ihnen unternommenen Anstrengungen trennen möchten Bauen Sie, was Sie gebaut haben, und betrachten Sie es mit einem neuen Paar Augen. Ich bin sogar vom obigen Entwickler darauf gestoßen, dass dies eine unmögliche Sache ist. Er meinte, ich hätte ein ähnliches Ego wie alle technisch versierten, aber benutzerunabhängigen Entwickler, und ich habe ihn immer wieder als falsch erwiesen, wenn sich Benutzer und Designer zu mir strömen, um genau zu besprechen, was zu tun ist. Das hört sich sehr egoistisch an, aber ich werde das mit dem Hinweis abwägen, dass ich kein so brillanter Programmierer bin, aber ich verstehe, was Benutzer und Designer wollen, und das hat mich in meinem Bereich, in dem dies besonders selten zu sein schien, besonders beliebt gemacht Qualität aus irgendeinem Grund. Als Programmierer sind wir wahrscheinlich eher daran gewöhnt, Tests durchzuführen, als mit gewöhnlichen, nicht-technischen Leuten umzugehen und Kontakte zu knüpfen.
Es gibt also eine Profilerstellung und eine ordnungsgemäße Messung, aber es besteht auch die grundlegende Notwendigkeit, sicherzustellen, dass Sie eine Operation mit der Art von Eingaben messen, die Benutzer aus der realen Welt tatsächlich für die Anwendung bereitstellen. Andernfalls können Sie sogar VTune oder CodeAnalyst oder gprof oder einen anderen Profiler in der Hand haben und trotzdem versuchen, Hotspots gegen einen für den Entwickler möglicherweise normalen, für den Benutzer jedoch unklaren Testfall zu optimieren, was den allgemeinen Anwendungsfall am Ende pessimiert zugunsten eines obskuren Anwendungsfalls, den nur wenige Benutzer in Betracht ziehen.
Letztendlich können alle Unpraktiken, die wir als Entwickler haben, gegen den eisernen Hammer abgewogen werden, der die Benutzer wirklich glücklich genug macht, ohne den Welthunger zu stillen, und die praktische Notwendigkeit, Geld zu verdienen, um die Miete zu bezahlen oder Bier zu kaufen oder Schau dir nackte Frauen an oder was auch immer du tun willst / musst. Alles andere ist potenziell gegen dieses grundlegende Geschäftsbedürfnis gerichtet, und jeder Entwickler, der so edel und heldenhaft ist, um zu vergessen, dass es darum geht, Geld zu verdienen und letztendlich die Benutzer zu befriedigen, damit sie zahlen, kann sich auf den Boden bringen und schalten Sie den Gott-Modus aus, indem Sie virtuelle Welten zu Gunsten der realen Welt erstellen. Wir können uns in Software-Metriken und -Praktiken verlieren, aber im Grunde genommen
quelle