2013-01-08 6 views
7

Desidero calcolare la memoria utilizzata da un oggetto. sys.getsizeof è grande, ma è superficiale (ad esempio, chiamato su una lista, non includerebbe la memoria presa dagli elementi della lista).Versione profonda di sys.getsizeof

Mi piacerebbe scrivere una versione "profonda" generica di sys.getsizeof. Capisco che c'è qualche ambiguità nella definizione di "profondo"; Sono perfettamente soddisfatto dello definition followed by copy.deepcopy.

Ecco il mio primo tentativo:

def get_deep_sizeof(x, level=0, processed=None): 
    if processed is None: 
     # we're here only if this function is called by client code, not recursively 
     processed = set() 
    processed.add(id(x)) 
    mem = sys.getsizeof(x) 
    if isinstance(x, collections.Iterable) and not isinstance(x, str): 
     for xx in x: 
      if id(xx) in processed: 
       continue 
      mem += get_deep_sizeof(xx, level+1, processed) 
      if isinstance(x, dict): 
       mem += get_deep_sizeof(x[xx], level+1, processed) 
    return mem 

Si soffre di due problemi noti, e un numero imprecisato di problemi sconosciuti:

  • Non so come attraversare un contenitore generico in un modo che cattura tutti gli oggetti collegati. Pertanto, ho ripetuto l'iter usando in e ho codificato il caso del dizionario (per includere i valori e non solo le chiavi). Ovviamente, questo non funzionerà per altre classi come il dizionario.
  • Ho dovuto codificare l'esclusione di str (che è un iterabile e tuttavia non ha collegamenti ad altri oggetti). Di nuovo, questo si interromperà se ci sono più oggetti del genere.

Ho il sospetto che l'uso di in non sia una buona idea, ma non sono sicuro di cos'altro fare.

+0

Ah, è una domanda doppia su http://stackoverflow.com/questions/5022725/how-do-i-measure-the-memory-usage-of-an-object-in-python e http: // stackoverflow.com/questions/1331471/in-memory-size-of-python-stucture. – max

risposta

8

Penso che lo Pympler ti abbia già battuto sul pugno di questo.

Da loro documentazione:

>>> from pympler.asizeof import asizeof 
>>> obj = [1, 2, (3, 4), 'text'] 
>>> asizeof(obj) 
176 

Se volete un esempio specifico, è possibile trovare la fonte per asizeofhere.

+0

Sembra fantastico. Tuttavia, sembra che non ci sia una soluzione elegante a questo problema; 'pympler' è hard datting' dict' (e consente di registrare altre classi per essere trattato come tale). Mi chiedo perché l'iterazione di tutti gli attributi (eccetto quelli appositamente esclusi) non funzioni ... – max