Ich versuche eine Funktion zu profilieren, die andere Funktionen aufruft. Ich rufe den Profiler wie folgt auf:
%Vor%Ich finde, dass der Profiler sagt, dass die ganze Zeit in der Funktion "foo ()" von mymodule verbracht wurde, anstatt sie in die Unterfunktionen foo () zu brekaen, was ich sehen will. Wie kann ich den Profiler die Leistung dieser Funktionen melden lassen?
danke.
Sie benötigen p.print_callees()
, um eine hierarchische Aufschlüsselung der Methodenaufrufe zu erhalten. Die Ausgabe ist ziemlich selbsterklärend: In der linken Spalte können Sie Ihre Funktion von Interesse finden, z. B. foo()
, dann werden in der rechten Spalte alle aufgerufenen Unterfunktionen und ihre gesamten und kumulativen Gesamtzeiten angezeigt. Breakdowns für diese Unteraufrufe sind ebenfalls enthalten etc.
Vielleicht haben Sie ein ähnliches Problem, also beschreibe ich hier mein Problem. Mein Profilierungscode sah so aus:
%Vor% Und die endgültige Profilerstellung enthielt nur events()
call. Und ich brauchte nicht so viel Zeit, um zu erkennen, dass ich ein leeres Profil hatte. Natürlich gab es mehr als einen Aufruf von foobar()
aus einem Client-Code, aber aussagekräftige Profilergebnisse wurden durch den letzten Aufruf mit leerer Schleife überschrieben.
Zuerst möchte ich sagen, dass ich das Problem des Fragestellers nicht replizieren konnte. Der Profiler (in py2.7) fällt definitiv in die aufgerufenen Funktionen und Methoden ab. (Die Dokumente für py3.6 sehen identisch aus, aber ich habe nicht auf py3 getestet.) Meine Vermutung ist, dass die ersten N davon sehr hochrangige Funktionen genannt wurden, indem man sie auf die Top-10-Renditen nach kumulativer Zeit beschränkte ein Minimum an Zeit und die Funktionen, die von foo()
aufgerufen wurden, fielen am Ende der Liste ab.
Ich habe mich entschieden, mit einigen großen Zahlen zu testen. Hier ist mein Testcode:
%Vor%Und die Include-Datei (Askers sehr ähnlich):
%Vor% Beachten Sie die letzte Zeile. Ich habe eine Ansicht hinzugefügt, die nach time
sortiert ist. Dies ist die Gesamtzeit, die in der Funktion " Zeit in Anrufen verbracht wurde." Unterfunktionen ". Ich finde diese Ansicht viel nützlicher, da sie tendenziell die Funktionen favorisiert, die tatsächlich arbeiten, und möglicherweise optimiert werden müssen.
Hier ist der Teil der Ergebnisse, von denen der Fragesteller aus gearbeitet hat ( cumulative
-sortiert):
Sehen Sie, wie die oberen 3 Funktionen in dieser Anzeige nur einmal aufgerufen wurden. Schauen wir uns die time
-sortierte Ansicht an:
Jetzt macht der Eintrag Nummer Eins Sinn. Es ist eine "naive" Strategie, durch wiederholte Multiplikation etwas auf die 200. Potenz zu heben. Lassen Sie uns es ersetzen:
%Vor%Und die Ergebnisse:
%Vor% Das ist eine schöne Verbesserung der Zeit. Jetzt ist str.format()
unser schlimmster Täter. Ich habe die Zeile in bar()
hinzugefügt, um die Länge der Zahl auszudrucken, weil mein erster Versuch (nur die Zahl zu berechnen und nichts damit zu tun) wegoptimiert wurde, und mein Versuch, das zu vermeiden (Drucken der Nummer, die wirklich groß wurde wirklich schnell) schien es, als würde es auf I / O blockieren, so kompromittierte ich beim Drucken die Länge der Nummer. Hey, das ist das Basis-10-Protokoll. Lass es uns versuchen:
Und die Ergebnisse:
%Vor% Hmm, noch eine ziemlich lange Zeit in bar()
, auch ohne str.format()
. Lassen Sie uns diesen Druck loswerden:
Und die Ergebnisse:
%Vor%Jetzt sieht es so aus, als ob die Dinge, die die eigentliche Arbeit machen, die am meisten genutzte Funktion sind, also denke ich, wir sind fertig mit der Optimierung.
Hoffe das hilft!