2010-12-08 7 views
38

Nachdem ich die Präsentation "Performance Angst" von Joshua Bloch gesehen hatte, las ich das Papier, das er in der Präsentation "Evaluating the Accuracy of Java Profilers" vorgeschlagen hatte. Unter Angabe der Schlussfolgerung:Wenn Profiler nicht die Antwort ist, welche anderen Möglichkeiten haben wir?

Unsere Ergebnisse störend sind, weil sie das Pro fi ler Unrichtigkeit anzuzeigen ist allgegenwärtig vorkommende in den meisten unserer sieben Benchmarks und in zwei Produktions JVM - und signifikante-alle vier die state-of-the -art-pro fi ler erzeugen falsche pro fi le. Falsche Pro fi le können leicht dazu führen, dass ein Performance-Analyst Zeit damit verbringt, kalte Methoden zu optimieren, die sich nur minimal auf die Leistung auswirken. Wir zeigen, dass ein Proof-of-Concept-Pro fi ler, die nicht Ertrag nicht aus den oben genannten Probleme nicht verwendet Punkte für die Probenahme leiden

Der Abschluss des Papiers ist, dass wir nicht wirklich das Ergebnis der Profilometer glauben kann. Aber was ist die Alternative zur Verwendung von Profilern? Sollten wir zurückgehen und unser Gefühl nur für die Optimierung nutzen?

UPDATE: Ein Punkt, der in der Diskussion zu übersehen scheint, ist Beobachter Effekt. Können wir einen Profiler bauen, der wirklich 'Beobachter Effekt' -free?

+2

+1 für das interessante lesen. – daveb

Antwort

40

Oh Mann, wo soll ich anfangen?

Zuerst bin ich erstaunt, dass dies Nachrichten sind. Zweitens ist das Problem nicht, dass Profiler schlecht sind, ist es einige Profiler sind schlecht. Die Autoren bauten eine, die ihrer Meinung nach gut ist, indem sie nur einige der Fehler vermeiden, die sie in den von ihnen bewerteten gefunden haben. Fehler sind häufig wegen einiger hartnäckiger myths about performance profiling.

Aber lassen Sie uns positiv sein. Will man Möglichkeiten für Speedup finden, es ist wirklich sehr einfach:

  • Sampling unkorreliert mit dem Zustand des Programms sein sollte.
    Das geschieht zu einer wirklich zufälligen Zeit, unabhängig davon, ob das Programm in I/O (außer Benutzereingabe) oder in GC oder in einer engen CPU-Schleife oder was auch immer ist.

  • Probenahme soll liest den Funktionsaufruf Stapel,
    , um zu bestimmen, welche Anweisungen zum Zeitpunkt der Probe „aktiv“ waren. Der Grund ist, dass jede Aufrufstelle (Punkt, an dem eine Funktion aufgerufen wird) einen Prozentsatz hat, der dem Bruchteil der Zeit entspricht, die sie auf dem Stapel ist. (Anmerkung:.. Das Papier betrifft ganz selbst Zeit, die massiven Auswirkungen vermeidbar Funktion ignoriert in großer Software rufen in der Tat der Grund hinter den ursprünglichen gprof diese Anrufe zu helfen, war zu finden)

  • Berichterstattung soll zeigen Prozent nach Zeile (nicht nach Funktion).
    Wenn eine "hot" -Funktion identifiziert wird, muss man immer noch darin nach den "heißen" Codezeilen suchen, die für die Zeit verantwortlich sind. Diese Information ist in den Beispielen! Warum verstecken Sie es? mit einer Genauigkeit von Messung, und nicht genug mit einer Genauigkeit von Lage

Eine fast universelle Fehler (, dass die Papieranteile) ist zu viel Beunruhigung. Hier ist zum Beispiel ein example of performance tuning , in dem eine Reihe von Leistungsproblemen identifiziert und behoben wurden, was eine kumulierte Beschleunigung von 43 Mal ergab. Es war nicht wichtig, die Größe jedes Problems genau zu kennen, bevor es repariert wurde, sondern seinen Standort zu kennen. Ein Phänomen der Leistungsoptimierung besteht darin, dass die Behebung eines Problems durch die Reduzierung der Zeit die Prozentsätze der verbleibenden Probleme vergrößert, sodass sie leichter zu finden sind. Solange irgendein Problem gefunden und behoben wird, wird Fortschritt in Richtung auf das Ziel gemacht, alle Probleme zu finden und zu beheben. Es ist nicht notwendig, sie in abnehmender Reihenfolge zu korrigieren, aber es ist wichtig, sie genau zu bestimmen.

Zum Thema statistische Genauigkeit der Messung, wenn ein Aufruf Punkt auf dem Stapel ist einige Prozent der Zeit F (wie 20%) und N (wie 100) zufällige Zeit Proben genommen werden, dann die Anzahl der Proben Das zeigt, dass der Aufrufpunkt eine Binomialverteilung ist, mit Mittelwert = NF = 20, Standardabweichung = sqrt (NF (1-F)) = sqrt (16) = 4. Der Prozentsatz der Proben, die ihn anzeigen, beträgt also 20%/- 4%. Also ist das genau? Nicht wirklich, aber ist das Problem gefunden worden? Genau.

In der Tat, je größer ein Problem ist, in Bezug auf Prozent, desto weniger Proben werden benötigt, um es zu lokalisieren. Wenn zum Beispiel 3 Proben genommen werden und ein Anrufpunkt auf 2 von ihnen erscheint, ist es sehr wahrscheinlich sehr teuer. (Konkret, es folgt eine Beta-Verteilung. Wenn Sie 4 einheitliche 0,1 Zufallszahlen generieren und sortieren, ist die Verteilung des dritten die Verteilung der Kosten für diesen Aufrufpunkt. Es ist meine ist (2 + 1)/(3 + 2) = 0.6, das sind also die erwarteten Einsparungen, wenn man diese Beispiele anführt.) INSERTED: Und der Beschleunigungsfaktor, den Sie erhalten, wird durch eine andere Verteilung, BetaPrime, und Durchschnitt ist 4. Also, wenn Sie nehmen 3 Proben, sehen ein Problem auf 2 von ihnen, und beseitigen Sie dieses Problem, im Durchschnitt werden Sie das Programm viermal schneller machen.

Es ist höchste Zeit, dass wir Programmierer beim Thema Profiling die Spinnweben aus dem Kopf rissen.

Disclaimer - die Zeitung konnte meinen Artikel nicht beziehen: Dunlavey, "Performance-Tuning mit Kosten auf Anweisungsebene, abgeleitet von Call-Stack-Sampling", ACM SIGPLAN Notices 42, 8 (August 2007), S. 4-8.

+4

Schöne Antwort. Obwohl ich damit nicht ganz einverstanden bin: ** wenn irgendein Problem gefunden und behoben wird, wird Fortschritt in Richtung auf das Ziel gemacht, alle Probleme zu finden und zu beheben **. Nicht alle Probleme können gelöst werden, manchmal sind Leistungsengpässe als Attribut der Anwendung vorhanden, was bedeutet, dass die ** anderen ** Probleme nicht vergrößert werden. Das ist sicherlich ein großes Problem. – nanda

+3

@nanda: Deshalb habe ich gesagt "und behoben". Grundsätzlich, wenn es die Probleme A, B, C, D und E unabhängig von ihrer relativen Größe gibt, vergrößert eine beliebige, die Sie finden und reparieren, unabhängig von der Reihenfolge, die anderen. Wenn es einen gibt, den du nicht reparieren kannst, dann nicht, aber du kannst trotzdem zu den anderen weitergehen. –

+0

@nanda: Hier ist ein interessantes bisschen Mathe zu diesem Thema: http://en.wikipedia.org/wiki/Rule_of_succession –

3

Es sei denn, Sie erstellen blutende Anwendungen, die jeden CPU-Zyklus benötigen, dann habe ich festgestellt, dass Profiler eine gute Möglichkeit sind, die 10% langsamsten Teile Ihres Codes zu finden. Als Entwickler würde ich argumentieren, dass alles, was Sie wirklich interessiert, in fast allen Fällen sein sollte.

Ich habe Erfahrung mit http://www.dynatrace.com/en/ und ich kann Ihnen sagen, dass es sehr gut darin ist, die niedrig hängenden Früchte zu finden.

Profiler sind wie jedes andere Werkzeug und sie haben ihre Macken, aber ich würde ihnen über einen Menschen jeden Tag vertrauen, um die Hotspots in Ihrer App zu finden.

+1

+1 Ich bin damit einverstanden, dass das Finden der schlimmsten Teile Ihrer App normalerweise dazu beiträgt, die Leistung auf ein akzeptables Niveau zu bringen. Die meisten Leistungssteigerungen werden nicht dadurch erreicht, dass die kleinen Methoden schneller gemacht werden, sondern weil sie einfach nicht aufgerufen werden, weil der Code auf hoher Ebene optimiert ist. – Daniel

+1

@Daniel: das Papier, das mit verbunden wird, macht einen überzeugenden Fall, dass Profiler oft * * * * nicht die langsamsten Teile des Codes richtig identifizieren. –

+0

@Michael: Meine Schuld! Ich wollte schreiben, dass das Finden der schlimmsten Teile Ihrer App, sogar mit einem Profiler, Ihnen die meisten der langsamsten Teile zeigen wird. Ich kam zu dem Schluss, dass die Lösung der Probleme oft nicht ein Fall von einigen Millis ist, sondern meistens dadurch, dass man die (vielleicht falsch gemessenen) Methoden überhaupt nicht anspricht. – Daniel

-1

Wenn Sie Profilern nicht vertrauen, können Sie in den Paranoia-Modus wechseln, indem Sie die aspektorientierte Programmierung verwenden, jede Methode in Ihrer Anwendung umschließen und dann einen Logger verwenden, um jeden Methodenaufruf zu protokollieren.

Ihre Anwendung wird wirklich langsamer, aber zumindest haben Sie eine genaue Anzahl, wie oft jede Methode aufgerufen wird. Wenn Sie auch sehen möchten, wie lange die einzelnen Methoden ausgeführt werden müssen, wenden Sie sich an jede Methode perf4j.

Nachdem Sie alle diese Statistiken in Textdateien gespeichert haben, verwenden Sie einige Werkzeuge, um alle notwendigen Informationen zu extrahieren und sie dann zu visualisieren. Ich schätze, das gibt Ihnen einen guten Überblick darüber, wie langsam Ihre Anwendung an bestimmten Orten ist.

+0

-1 Das ist nicht besser als das, was gute Profiler mit Agent Instrumentierung wie JProfiler (http://www.ej-technologies.com/products/jprofiler/overview.html) bereits tun. – Daniel

+0

@Daniel: Es ist immer noch ein alternativer Ansatz zur Verwendung eines Profilers, wenn Sie einem nicht vertrauen. – darioo

+0

Ja, aber wenn Sie Profilern nicht zu den Leistungsergebnissen vertrauen (Methodenaufrufe zählten hier nicht, da sie immer noch zuverlässig von Profilern gemessen werden), ist der Ansatz, AspectJ in Kombination mit perf4j zu verwenden, noch irreführender. – Daniel

8

Wenn ich es richtig gelesen habe, das Papier spricht nur über sample-based Profiling. Viele Profiler führen auch instrumentenbasierte Profilerstellung durch. Es ist viel langsamer und hat einige andere Probleme, aber es sollte nicht unter den Voreingenommenheiten leiden, über die das Papier spricht.

Der Abschluss des Papiers ist, dass wir können das Ergebnis von Profilometer nicht wirklich glauben. Aber dann, was ist die Alternative Profiler zu verwenden.

Nein.Die Schlussfolgerung des Papiers ist, dass die Messmethoden der aktuellen Profilierer spezifische Mängel aufweisen. Sie schlagen eine Lösung vor. Das Papier ist ziemlich neu. Ich würde erwarten, dass Profiler diesen Fix schließlich implementieren. Bis dahin ist sogar ein defekter Profiler immer noch viel besser als "Gefühl".

+0

Wie wäre es mit dem zweiten Grund: "Beobachtereffekt"? Jeder Profiler wird das Problem erleiden und die einzige Möglichkeit, den Beobachtereffekt zu entfernen, ist den Beobachter zu entfernen, dh keine Profiler zu verwenden. – nanda

+1

@nanda: Aber klar, keinen Profiler zu benutzen, weil er die Performance beeinflusst, ist wie kein Kuchen essen, weil er sich drehen könnte um schrecklich zu schmecken.Es ist nicht möglich, über Hotspots ohne irgendeine Beobachtung zu lernen (außer vielleicht in erfundenen Beispielen, die nicht von Benutzereingaben abhängen), aber wenn Sie versuchen zu optimieren, ohne zu wissen, wo es signifikante Auswirkungen hat, sind Ihre Chancen ziemlich schlecht. 20 Regel. – delnan

+0

"implementieren Sie diesen Fix schließlich" Das wird Fortschritt sein, aber immer noch unzureichend. Aus meiner Sicht muss sich der Schwerpunkt von der Messung zum Finden ändern. [Hier ist eine sehr kurze Erklärung, was ich meine.] (Http://StackOverflow.com/questions/4468022/how-to-measure/4501805#4501805) –

-3

Eigentlich sind Sie besser auf Datenbankebene profilieren. Die meisten Unternehmensdatenbanken bieten die Möglichkeit, die häufigsten Abfragen über einen bestimmten Zeitraum hinweg anzuzeigen. Fangen Sie an, an diesen Abfragen zu arbeiten, bis die oberen weniger als 300 ms oder weniger sind und Sie große Fortschritte gemacht haben. Profiler sind nützlich, um das Verhalten des Heapspeichers zu zeigen und um blockierte Threads zu identifizieren, aber ich persönlich habe nie viel Erfahrung mit den Entwicklungsteams bei der Identifizierung von heißen Methoden oder großen Objekten gesammelt.

+0

Datenbanken sind hier nicht das Ziel, noch interagieren alle Java-App mit Datenbanken . –