2009-02-19 10 views
22

Używam iPython do uruchomienia mojego kodu. Zastanawiam się, czy istnieje moduł lub polecenie, które pozwoliłoby mi sprawdzić wykorzystanie pamięci obiektu. Na przykład:Jak mogę sprawdzić wykorzystanie pamięci obiektów w iPythonie?

In [1]: a = range(10000) 
In [2]: %memusage a 
Out[2]: 1MB 

Coś takiego jak %memusage <object> i zwróć pamięć używaną przez obiekt.

zduplikowane

Find out how much memory is being used by an object in Python

+0

Duplikat : http://stackoverflow.com/questions/33978/find-out-how-much-memory-is-being-used-by-an-object-in-python, http://stackoverflow.com/questions/512893/pamięć-wykorzystanie-w-dużych-strukturach danych-manipulacja-przetwarzanie –

+0

Związane również: http://stackoverflow.com/questions/13566 4/ile-bajtów-na-element-jest-w-python-lista-tuple/159844 – Constantin

+1

Przepraszam. Chcę tylko zapytać, czy jest jakaś implementacja tej funkcji w ipython, lub moduł do dodawania funkcji "magic" w ipython (Ponieważ używam tego do testowania bardzo dużo.) – Ross

Odpowiedz

32

Niestety nie jest to możliwe, ale istnieje wiele sposobów zbliżenia odpowiedź:

  1. dla bardzo prostych obiektów (np. Ints, string, floats, doubles), które są reprezentowane mniej więcej jako proste typy języka C, można po prostu obliczyć liczbę bajtów tak jak w przypadku John Mulder's solution.

  2. Dla bardziej złożonych obiektów dobrym przybliżeniem jest serializacja obiektu do ciągu znaków przy użyciu cPickle.dumps. Długość łańcucha jest dobrym przybliżeniem ilości pamięci wymaganej do przechowywania obiektu.

Istnieje jeden duży szkopuł z rozwiązaniem 2, który polega na tym, że obiekty zwykle zawierają odniesienia do innych obiektów. Na przykład dyktaf zawiera klucze łańcuchowe i inne obiekty jako wartości. Te inne obiekty mogą być udostępniane. Ponieważ pickle zawsze próbuje wykonać pełną serializację obiektu, zawsze przeinwestuje ilość pamięci wymaganej do przechowywania obiektu.

+1

Ale jeśli wybierzesz listę zawierającą wszystkie obiekty root, które cię interesują, nie będzie przeszacowania. – Constantin

+0

Dziękuję bardzo. Ale zastanawiam się, czy pikle zrobi jakąkolwiek kompresję, czy nie. – Ross

+0

Nie, pikle nie są kompresowane. Po prostu eliminuje nadmiarowość. –

13

UPDATE: Oto another, może być bardziej dokładny przepis szacowania rozmiaru obiektu pytona.

Oto thread adresowania podobne pytanie

Proponowane rozwiązanie jest napisanie własnego ... korzystania z niektórych szacunków znanej wielkości prymitywów, obiekt napowietrznych Pythona, oraz wielkość wbudowanych typów kontenerów.

Ponieważ kod nie jest tak długo, tutaj jest bezpośrednią kopią go:

def sizeof(obj): 
    """APPROXIMATE memory taken by some Python objects in 
    the current 32-bit CPython implementation. 

    Excludes the space used by items in containers; does not 
    take into account overhead of memory allocation from the 
    operating system, or over-allocation by lists and dicts. 
    """ 
    T = type(obj) 
    if T is int: 
     kind = "fixed" 
     container = False 
     size = 4 
    elif T is list or T is tuple: 
     kind = "variable" 
     container = True 
     size = 4*len(obj) 
    elif T is dict: 
     kind = "variable" 
     container = True 
     size = 144 
     if len(obj) > 8: 
      size += 12*(len(obj)-8) 
    elif T is str: 
     kind = "variable" 
     container = False 
     size = len(obj) + 1 
    else: 
     raise TypeError("don't know about this kind of object") 
    if kind == "fixed": 
     overhead = 8 
    else: # "variable" 
     overhead = 12 
    if container: 
     garbage_collector = 8 
    else: 
     garbage_collector = 0 
    malloc = 8 # in most cases 
    size = size + overhead + garbage_collector + malloc 
    # Round to nearest multiple of 8 bytes 
    x = size % 8 
    if x != 0: 
     size += 8-x 
     size = (size + 8) 
    return size 
+0

zapomniałeś płynąć .. – drevicko

+1

To jest dość trudne zakodowane rozwiązanie. Nie działałoby to, gdybyśmy mieli listę dużych słowników lub jakiejkolwiek innej struktury danych! – user2685079

16

Jeśli używasz numpy array, można użyć atrybutu ndarray.nbytes ocenić jego wielkość pamięci:

from pylab import * 
d = array([2,3,4,5]) 
d.nbytes 
#Output: 32 
+3

Jest to również pokazane przez magię IPython '% whos'. – gerrit

2

do całkowitej wielkości mieszkańców (w MB):

from sys import getsizeof 
sum([getsizeof(k) for k in locals().keys()])/10**6 
+2

to dostaje rozmiar klucza, a nie wartość. również, nie trzeba używać rozumienia list, gdy generator zrobi – Kapocsi

Powiązane problemy