2010-01-22 8 views
19

Me sorprendió que sys.getsizeof(10000*[x]) sea 40036 independientemente de x: 0, "a", 1000 * "a", {}.
¿Hay un deep_getsizeof que considere correctamente los elementos que comparten memoria?
(La pregunta vino de mirar las tablas de base de datos en memoria como gama (1000000) -> nombres de provincias: lista o dict?)
(Python 2.6.4 es en un Mac PPC.)Python deep getsizeof list with contents?

Agregado: 10000 * ["Mississippi"] es 10000 apuntadores a un "Mississippi", como varias personas han señalado. Pruebe esto:

nstates = [AlabamatoWyoming() for j in xrange(N)] 

donde AlabamatoWyoming() -> una cadena "Alabama" .. "Wyoming". ¿Qué es deep_getsizeof (nstates)?
(¿Cómo podemos decir

  • un deep_getsizeof adecuada:? Difícil, ~ gc trazador
  • estimación a partir de memoria virtual
  • dentro de los conocimientos de la aplicación de pitón
  • conjetura

. Agregado 25jan: ver también when-does-python-allocate-new-memory-for-identical-strings

Respuesta

5

un vistazo a guppy/heapy; No he jugado demasiado conmigo, pero algunos de mis compañeros de trabajo lo han usado para crear perfiles de memoria con buenos resultados.

La documentación podría ser mejor, pero this howto hace un trabajo decente de explicar los conceptos básicos.

+0

Gracias Pär, lo intentaré; muestra cuán difícil es el problema ¿Alguno de sus compañeros de trabajo tiene una breve nota sobre cómo guardar la memoria en Python, que respondería, por ejemplo, a Python? rango (1000000) -> nombres de las provincias: ¿list o dict? – denis

+1

vínculo muerto allí – MohamedEzz

14

10000 * [x] producirá una lista de 10000 veces el mismo objeto, por lo tanto, el tamaño es más cercano a lo correcto de lo que cree. Sin embargo, un tamaño profundo es muy problemático porque es imposible decirle a Python cuando quiere detener la medición. Cada objeto hace referencia a un objeto tipo. ¿Debería contarse el tipo de objeto? ¿Qué pasa si la referencia al tipoobjeto es la última, por lo que si eliminaste el objeto también se iría? ¿Qué pasa si tiene varios objetos (diferentes) en la lista que hacen referencia al mismo objeto de cadena? ¿Debe contarse una vez o varias veces?

En resumen, para obtener el tamaño de una estructura de datos es muy complicado, y no debería haber sido añadido sys.getsizeof(): S

+0

+1 debe definir dónde detenerse para cualquier cosa profunda. ¿Desea informar la memoria compartida por otras partes del código? Entonces eso es casi todo, ya que tiene una referencia a 'objeto'. – nosklo

5

Si lista sólo está sosteniendo objetos con la misma longitud que usted podría conseguir una número estimación más precisa al hacer esto

def getSize(array): 
    return sys.getsizeof(array) + len(array) * sys.getsizeof(array[0]) 

Obviamente no va a funcionar tan bien para las cadenas de longitud variable.

Si solo quiere calcular el tamaño para la depuración o durante el desarrollo y no le importa el rendimiento, puede repetir todos los elementos recursivamente y calcular el tamaño total. Tenga en cuenta que esta solución no manejará múltiples referencias al mismo objeto correctamente.

0

mylist = 10000 * [x] significa crear una lista de tamaño 10000 con 10000 referencias al objeto x.

Objeto x es no copiado - ¡solo existe uno en la memoria!

Así que para usar getsizeof, sería: sys.getsizeof(mylist) + sys.getsizeof(x)

+0

Ese no es el caso para los tipos inmutables, sys.getsizeof (rango (1000)) devuelve el mismo tamaño que sys.getsizeof ([0] * 1000) –

+0

@Nadia Alramli: Exactamente mi punto: ambos ejemplos ejecutan 'sys. getsizeof' en una lista de 1000 elementos; no importa qué elementos sean, por lo que devolverán el mismo tamaño. – nosklo