2013-05-16 3 views
6

Ich möchte Zeit und Speichernutzung der Klassenmethode Profil. Ich fand keine Out-of-Box-Lösung dafür (gibt es solche Module?), Und ich entschied mich, timeit für die Zeitprofilierung und memory_usage von memory_profiler Modul zu verwenden.Wie verwendet man memory_profiler (Python-Modul) mit Klassenmethoden?

Ich konfrontiert ein Problem der Profilierungsmethoden mit memory_profiler. Ich habe verschiedene Varianten ausprobiert, und keiner von ihnen hat funktioniert.

Wenn ich versuche, aus functools teilweise zu nutzen, ich diesen Fehler:

File "/usr/lib/python2.7/site-packages/memory_profiler.py", line 126, in memory_usage 
    aspec = inspect.getargspec(f) 
File "/usr/lib64/python2.7/inspect.py", line 815, in getargspec 
    raise TypeError('{!r} is not a Python function'.format(func)) 
TypeError: <functools.partial object at 0x252da48> is not a Python function 

By the way, genau der gleiche Ansatz arbeitet mit timeit Funktion in Ordnung.

Wenn ich versuche, lambda zu verwenden, da war ich diesen Fehler hätte:

File "/usr/lib/python2.7/site-packages/memory_profiler.py", line 141, in memory_usage 
    ret = parent_conn.recv() 
IOError: [Errno 4] Interrupted system call 

Wie kann ich Klassenmethoden mit memory_profiler umgehen?

PS: Ich habe Speicher-Profiler (0.26) (mit Pip installiert).

UPD: Es ist eigentlich Bug. Sie können den Status hier überprüfen: https://github.com/fabianp/memory_profiler/issues/47

Antwort

5

Wenn Sie die Änderung der Arbeitsspeicher für die Python VM sehen möchten, können Sie psutil verwenden. Hier ist ein einfaches Dekorateur mit psuil, die die Änderung im Speicher gedruckt wird:

import functools 
import os 
import psutil 


def print_memory(fn): 
    def wrapper(*args, **kwargs): 
     process = psutil.Process(os.getpid()) 
     start_rss, start_vms = process.get_memory_info() 
     try: 
      return fn(*args, **kwargs) 
     finally: 
      end_rss, end_vms = process.get_memory_info() 
      print((end_rss - start_rss), (end_vms - start_vms)) 
    return wrapper 


@print_memory 
def f(): 
    s = 'a'*100 

Aller Wahrscheinlichkeit nach wird die Ausgabe sehen Sie keine Änderung im Speicher sagen. Dies liegt daran, dass die Python-VM für kleine Zuordnungen möglicherweise nicht mehr Speicher vom Betriebssystem anfordern muss. Wenn Sie ein großes Array zuweisen, sehen Sie etwas anderes:

Hier sollten Sie einige Änderungen im Speicher sehen.

Wenn Sie sehen möchten, wie viel Speicherplatz von jedem Objekt zugewiesen verwendet wird, das einzige Werkzeug, das ich kenne, ist heapy

In [1]: from guppy import hpy; hp=hpy() 

In [2]: h = hp.heap() 

In [3]: h 
Out[3]: 
Partition of a set of 120931 objects. Total size = 17595552 bytes. 
Index Count %  Size % Cumulative % Kind (class/dict of class) 
    0 57849 48 6355504 36 6355504 36 str 
    1 29117 24 2535608 14 8891112 51 tuple 
    2 394 0 1299952 7 10191064 58 dict of module 
    3 1476 1 1288416 7 11479480 65 dict (no owner) 
    4 7683 6 983424 6 12462904 71 types.CodeType 
    5 7560 6 907200 5 13370104 76 function 
    6 858 1 770464 4 14140568 80 type 
    7 858 1 756336 4 14896904 85 dict of type 
    8 272 0 293504 2 15190408 86 dict of class 
    9 304 0 215064 1 15405472 88 unicode 
<501 more rows. Type e.g. '_.more' to view.> 

ich es nicht in einer langen Zeit verwendet habe, so empfehle ich das Experimentieren und das Lesen die Dokumentation. Beachten Sie, dass es für eine Anwendung, die eine große Menge an Speicher verwendet, sehr langsam sein kann, diese Informationen zu berechnen.

+0

Vielen Dank. Ich hab es geschafft. Es klappt. – rominf