Ich habe mich kürzlich für Algorithmen interessiert und begonnen, sie zu untersuchen, indem ich eine naive Implementierung geschrieben und sie dann auf verschiedene Arten optimiert habe.
Ich bin bereits mit dem Standard-Python-Modul für die Profilerstellung zur Laufzeit vertraut (für die meisten Dinge habe ich festgestellt, dass die Timeit Magic-Funktion in IPython ausreichend ist), aber ich bin auch an der Speichernutzung interessiert, damit ich auch diese Kompromisse untersuchen kann ( z. B. die Kosten für das Zwischenspeichern einer Tabelle zuvor berechneter Werte im Vergleich zur erneuten Berechnung nach Bedarf). Gibt es ein Modul, das die Speichernutzung einer bestimmten Funktion für mich erfasst?
Antworten:
Dieser wurde bereits hier beantwortet: Python Memory Profiler
Grundsätzlich machen Sie so etwas (zitiert nach Guppy-PE ):
quelle
Python 3.4 enthält ein neues Modul :
tracemalloc
. Es enthält detaillierte Statistiken darüber, welcher Code den meisten Speicher zuweist. In diesem Beispiel werden die drei obersten Zeilen angezeigt, in denen Speicher zugewiesen wird.Und hier sind die Ergebnisse:
Wann ist ein Speicherverlust kein Leck?
Dieses Beispiel ist großartig, wenn der Speicher am Ende der Berechnung noch gehalten wird, aber manchmal haben Sie Code, der viel Speicher zuweist und dann alles freigibt. Es ist technisch gesehen kein Speicherverlust, aber es verbraucht mehr Speicher als Sie denken. Wie können Sie die Speichernutzung verfolgen, wenn alles freigegeben wird? Wenn es sich um Ihren Code handelt, können Sie wahrscheinlich Debugging-Code hinzufügen, um während der Ausführung Snapshots zu erstellen. Wenn nicht, können Sie einen Hintergrundthread starten, um die Speichernutzung zu überwachen, während der Hauptthread ausgeführt wird.
Hier ist das vorherige Beispiel, in dem der gesamte Code in die
count_prefixes()
Funktion verschoben wurde . Wenn diese Funktion zurückkehrt, wird der gesamte Speicher freigegeben. Ich habe auch einigesleep()
Aufrufe hinzugefügt , um eine langfristige Berechnung zu simulieren.Wenn ich diese Version ausführe, ist die Speichernutzung von 6 MB auf 4 KB gesunken, da die Funktion nach Beendigung den gesamten Speicher freigegeben hat.
Hier ist eine Version, die von einer anderen Antwort inspiriert wurde und einen zweiten Thread zur Überwachung der Speichernutzung startet.
Mit dem
resource
Modul können Sie die aktuelle Speichernutzung überprüfen und den Snapshot von der maximalen Speichernutzung speichern. In der Warteschlange kann der Hauptthread dem Speichermonitor-Thread mitteilen, wann sein Bericht gedruckt und heruntergefahren werden soll. Wenn es ausgeführt wird, wird der vomlist()
Aufruf verwendete Speicher angezeigt:Wenn Sie unter Linux arbeiten, ist dies möglicherweise
/proc/self/statm
nützlicher als dasresource
Modul.quelle
long_running()
innerhalb dercount_prefixes()
Funktion, werden die maximalen RSS-Werte erst gedruckt, wenn sielong_running()
zurückgegeben werden. Oder irre ich mich?memory_monitor()
wird in einem separaten Thread von ausgeführtcount_prefixes()
. Die einzigen Möglichkeiten, wie sich einer auf den anderen auswirken kann, sind die GIL und die Nachrichtenwarteschlange, an die ich übergebememory_monitor()
. Ich vermute, dass beimcount_prefixes()
Aufrufensleep()
der Thread-Kontext zum Wechseln angeregt wird. Wennlong_running()
es nicht sehr lange dauert, wechselt der Thread-Kontext möglicherweise erst, wenn Sie densleep()
Rückruf erneut ausführencount_prefixes()
. Wenn das keinen Sinn ergibt, poste eine neue Frage und verlinke sie von hier aus.Wenn Sie nur die Speichernutzung eines Objekts betrachten möchten ( Antwort auf eine andere Frage )
quelle
asizeof
asizeof
kann zu RSS beitragen, ja. Ich bin mir nicht sicher, was Sie sonst noch mit "verwandt mit" meinen.tracemalloc
Lösung unterhalb einer Größenordnung schnellerOffenlegung:
Aber schön wegen seiner Einfachheit:
Fügen
using("Label")
Sie einfach ein, wo Sie sehen möchten, was los ist. Beispielsweisequelle
usage[2]
Sie sich ansehenru_maxrss
, sehen Sie , was nur der Teil des Prozesses ist, der resident ist . Dies hilft nicht viel, wenn der Prozess auch nur teilweise auf die Festplatte übertragen wurde.resource
ist ein Unix-spezifisches Modul, das unter Windows nicht funktioniert.ru_maxrss
(d. H.usage[2]
) Sind kB, keine Seiten, sodass diese Zahl nicht mit multipliziert werden mussresource.getpagesize()
.Da die akzeptierte Antwort und auch die Antwort mit der nächsthöheren Stimme meiner Meinung nach einige Probleme haben, möchte ich eine weitere Antwort anbieten, die eng auf der Antwort von Ihor B. basiert, mit einigen kleinen, aber wichtigen Änderungen.
Mit dieser Lösung können Sie die Profilerstellung ausführen, indem Sie entweder einen Funktionsaufruf mit der
profile
Funktion umschließen und aufrufen oder Ihre Funktion / Methode mit dem@profile
Dekorator dekorieren .Die erste Technik ist nützlich, wenn Sie Code von Drittanbietern profilieren möchten, ohne die Quelle zu beeinträchtigen, während die zweite Technik etwas "sauberer" ist und besser funktioniert, wenn es Ihnen nichts ausmacht, die Quelle der von Ihnen verwendeten Funktion / Methode zu ändern Profil erstellen wollen.
Ich habe auch die Ausgabe so geändert, dass Sie RSS, VMS und gemeinsam genutzten Speicher erhalten. Die "Vorher" - und "Nachher" -Werte interessieren mich nicht sehr, sondern nur das Delta, also habe ich diese entfernt (wenn Sie mit der Antwort von Ihor B. vergleichen).
Profiling-Code
Beispiel für die Verwendung unter der Annahme, dass der obige Code wie folgt gespeichert ist
profile.py
:Dies sollte zu einer Ausgabe ähnlich der folgenden führen:
Ein paar wichtige Schlussbemerkungen:
profile(my_function, arg)
profilierenmy_function(arg)
quelle
Im Folgenden finden Sie einen einfachen Funktionsdekorator, mit dem Sie nachverfolgen können, wie viel Speicher der Prozess vor dem Funktionsaufruf, nach dem Funktionsaufruf verbraucht hat und was der Unterschied ist:
Hier ist mein Blog, der alle Details beschreibt. ( archivierter Link )
quelle
process.memory_info().rss
nicht der Fall seinprocess.get_memory_info().rss
. verbunden stackoverflow.com/questions/41012058/psutil-error-on-macosVielleicht hilft es:
< siehe zusätzliche >
quelle
quelle