2009-02-19 16 views
22

Estoy usando iPython para ejecutar mi código. Me pregunto si hay algún módulo o comando que me permita verificar el uso de memoria de un objeto. Por ejemplo:¿Cómo puedo verificar el uso de memoria de los objetos en iPython?

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

Algo así como %memusage <object> y devolver la memoria utilizada por el objeto.

Duplicar

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

+0

Duplicar : http://stackoverflow.com/questions/33978/find-out-how-much-memory-is-being-used-by-an-object-in-python, http://stackoverflow.com/questions/512893/memory-use-in-large-data-structures-manipulation-processing –

+0

También relacionado: http://stackoverflow.com/questions/13566 4/how-many-bytes-per-element-are-there-in-a-python-list-tuple/159844 – Constantin

+1

Lo siento. Solo quiero preguntar si hay alguna implementación de estas características en ipython, o módulo para eso agregando la función "mágica" en ipython (ya que lo uso para probar mucho). – Ross

Respuesta

32

Desafortunadamente esto no es posible, pero hay un número de maneras de aproximar la respuesta:

  1. para objetos muy simples (por ejemplo, ints, strings, floats, doubles) que se representan más o menos como simples tipos de lenguaje C, puede simplemente calcular el número de bytes como con John Mulder's solution.

  2. Para objetos más complejos, una buena aproximación es serializar el objeto a una cadena usando cPickle.dumps. La longitud de la cadena es una buena aproximación de la cantidad de memoria requerida para almacenar un objeto.

Hay una gran pega con la solución 2, que es que los objetos suelen contener referencias a otros objetos. Por ejemplo, un dict contiene string-keys y otros objetos como valores. Esos otros objetos pueden ser compartidos. Como pickle siempre intenta hacer una serialización completa del objeto, siempre sobreestimará la cantidad de memoria requerida para almacenar un objeto.

+1

Pero si selecciona una lista que contenga todos los objetos raíz que le interesan, no habrá sobreestimación. – Constantin

+0

Muchas gracias. Pero me pregunto si pickle hará alguna compresión o no. – Ross

+0

No, la salmuera no se comprime. Simplemente elimina la redundancia. –

13

ACTUALIZACIÓN: Aquí es another, tal vez la receta más completa para estimar el tamaño de un objeto Python.

Aquí es una thread hacer frente a una pregunta similar

La solución propuesta es escribir su propia ... usando algunas estimaciones del tamaño conocido de primitivas, gastos generales objeto de Python, y los tamaños de construido en los tipos de contenedores.

Dado que el código no es tan largo, aquí es una copia directa de la misma:

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

olvidaste el flotador ... – drevicko

+1

Esta es una solución bastante codificada. ¡Esto no funcionaría si tenemos una lista de diccionarios grandes o cualquier otra estructura de datos! – user2685079

16

Si está utilizando un numpy array, a continuación, puede utilizar el atributo ndarray.nbytes para evaluar su tamaño en memoria:

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

Esto también se muestra con la magia de IPython '% whos'. – gerrit

2

para el tamaño total de los locales (en MB):

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

esto obtiene el tamaño de la clave, no el valor. Además, no es necesario usar una lista de comprensión cuando un generador lo hará – Kapocsi

Cuestiones relacionadas