2013-05-16 22 views
6

Chcę profilu czas i wykorzystanie pamięci metody klasy. Nie znalazłem dla tego rozwiązania z pudełka (czy są takie moduły?) I zdecydowałem się użyć timeit do profilowania czasu i memory_usage z modułu memory_profiler.Jak korzystać z memory_profiler (moduł python) metodami klasy?

Napotkałem problem z metodami profilowania z memory_profiler. Próbowałem różnych wariantów i żaden z nich nie działał.

Kiedy próbuję użyć częściowy z functools, otrzymuję ten błąd:

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 

Nawiasem mówiąc, dokładnie takie samo podejście działa prawidłowo z timeit funkcji.

Kiedy próbuję użyć lambda jak to mam ten błąd:

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 

Jak mogę obsługiwać metod klasy z memory_profiler?

PS: Mam profiler pamięci (0,26) (zainstalowany z pipem).

UPD: To właściwie błąd. Możesz sprawdzić status tutaj: https://github.com/fabianp/memory_profiler/issues/47

Odpowiedz

5

Jeśli chcesz zobaczyć zmianę w pamięci przydzielonej do maszyny wirtualnej Python, możesz użyć psutil. Oto prosty dekorator użyciu psuil które drukują zmianę w pamięci:

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 

Według wszelkiego prawdopodobieństwa, wyjście widać powie żadnej zmiany w pamięci. Dzieje się tak, ponieważ w przypadku niewielkich alokacji maszyna wirtualna Python może nie wymagać więcej pamięci z systemu operacyjnego. Jeśli przydzielisz dużą tablicę, zobaczysz coś innego:

import numpy 
@print_memory 
def f(): 
    return numpy.zeros((512,512)) 

Tutaj powinna pojawić się jakaś zmiana w pamięci.

Jeśli chcesz zobaczyć, ile pamięci jest używana przez każdego przydzielonego obiektu, jedynym narzędziem Znam to 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.> 

Nie używałem go od dłuższego czasu, więc polecam eksperymentowania i czytanie dokumentacja. Zwróć uwagę, że w przypadku aplikacji używającej dużej ilości pamięci obliczanie tych informacji może być bardzo powolne.

+0

Dziękuję. Mam to. To działa. – rominf