Tamaño en memoria de una estructura de Python

¿Hay una referencia para el tamaño de memoria de la estructura de datos de Python en plataformas de 32 y 64 bits?

Si no, sería bueno tenerlo en SO. Cuanto más exhaustivo, mejor! Entonces, ¿cuántos bytes son utilizados por las siguientes estructuras de Python (según el tipo de contenido y el tipo de contenido cuando sea relevante)?

  • int
  • float
  • referencia
  • str
  • cadena de Unicode
  • tuple
  • list
  • dict
  • set
  • array.array
  • numpy.array
  • deque
  • objeto de clases de nuevo estilo
  • objeto de clases de estilo antiguo
  • … y todo lo que estoy olvidando!

(Para los contenedores que solo contienen referencias a otros objetos, obviamente no queremos contar el tamaño del elemento en sí mismos, ya que podría ser compartido).

Además, ¿hay una manera de obtener la memoria utilizada por un objeto en tiempo de ejecución (recursivamente o no)?

La recomendación de una pregunta anterior sobre esto fue usar sys.getsizeof () , citando:

 >>> import sys >>> x = 2 >>> sys.getsizeof(x) 14 >>> sys.getsizeof(sys.getsizeof) 32 >>> sys.getsizeof('this') 38 >>> sys.getsizeof('this also') 48 

Usted podría tomar este enfoque:

 >>> import sys >>> import decimal >>> >>> d = { ... "int": 0, ... "float": 0.0, ... "dict": dict(), ... "set": set(), ... "tuple": tuple(), ... "list": list(), ... "str": "a", ... "unicode": u"a", ... "decimal": decimal.Decimal(0), ... "object": object(), ... } >>> for k, v in sorted(d.iteritems()): ... print k, sys.getsizeof(v) ... decimal 40 dict 140 float 16 int 12 list 36 object 8 set 116 str 25 tuple 28 unicode 28 

2012-09-30

python 2.7 (linux, 32 bits):

 decimal 36 dict 136 float 16 int 12 list 32 object 8 set 112 str 22 tuple 24 unicode 32 

Python 3.3 (Linux, 32 bits)

 decimal 52 dict 144 float 16 int 14 list 32 object 8 set 112 str 26 tuple 24 unicode 26 

2016-08-01

OSX, Python 2.7.10 (predeterminado, 23 de octubre de 2015, 19:19:21) [Compatible con GCC 4.2.1 Apple LLVM 7.0.0 (clang-700.0.59.5)] en Darwin

 decimal 80 dict 280 float 24 int 24 list 72 object 16 set 232 str 38 tuple 56 unicode 52 

He estado felizmente usando pympler para tales tareas. Es compatible con muchas versiones de Python, el módulo de asizeof especial en particular se remonta a 2.2.

Por ejemplo, al usar el ejemplo from pympler import asizeof pero con from pympler import asizeof al inicio e print asizeof.asizeof(v) al final, veo (sistema Python 2.5 en MacOSX 10.5):

 $ python pymp.py set 120 unicode 32 tuple 32 int 16 decimal 152 float 16 list 40 object 0 dict 144 str 32 

Claramente hay una aproximación aquí, pero me parece muy útil para el análisis y ajuste de la huella.

Estas respuestas recogen información de tamaño superficial. Sospecho que los visitantes a esta pregunta terminarán aquí buscando responder la pregunta, “¿Qué tan grande es este objeto complejo en la memoria?”

Aquí hay una gran respuesta: https://goshippo.com/blog/measure-real-size-any-python-object/

El punchline:

 import sys def get_size(obj, seen=None): """Recursively finds size of objects""" size = sys.getsizeof(obj) if seen is None: seen = set() obj_id = id(obj) if obj_id in seen: return 0 # Important mark as seen *before* entering recursion to gracefully handle # self-referential objects seen.add(obj_id) if isinstance(obj, dict): size += sum([get_size(v, seen) for v in obj.values()]) size += sum([get_size(k, seen) for k in obj.keys()]) elif hasattr(obj, '__dict__'): size += get_size(obj.__dict__, seen) elif hasattr(obj, '__iter__') and not isinstance(obj, (str, bytes, bytearray)): size += sum([get_size(i, seen) for i in obj]) return size 

Utilizado como tal:

 In [1]: get_size(1) Out[1]: 24 In [2]: get_size([1]) Out[2]: 104 In [3]: get_size([[1]]) Out[3]: 184 

Si desea conocer más a fondo el modelo de memoria de Python, aquí hay un gran artículo que tiene un fragmento de código de “tamaño total” similar como parte de una explicación más extensa: https://code.tutsplus.com/tutorials/understand-how- mucha memoria-tu-python-objetos-uso – cms-25609

Probar el generador de perfiles de memoria. perfilador de memoria

 Line # Mem usage Increment Line Contents ============================================== 3 @profile 4 5.97 MB 0.00 MB def my_func(): 5 13.61 MB 7.64 MB a = [1] * (10 ** 6) 6 166.20 MB 152.59 MB b = [2] * (2 * 10 ** 7) 7 13.61 MB -152.59 MB del b 8 13.61 MB 0.00 MB return a 

También puedes usar el módulo guppy .

 >>> from guppy import hpy; hp=hpy() >>> hp.heap() Partition of a set of 25853 objects. Total size = 3320992 bytes. Index Count % Size % Cumulative % Kind (class / dict of class) 0 11731 45 929072 28 929072 28 str 1 5832 23 469760 14 1398832 42 tuple 2 324 1 277728 8 1676560 50 dict (no owner) 3 70 0 216976 7 1893536 57 dict of module 4 199 1 210856 6 2104392 63 dict of type 5 1627 6 208256 6 2312648 70 types.CodeType 6 1592 6 191040 6 2503688 75 function 7 199 1 177008 5 2680696 81 type 8 124 0 135328 4 2816024 85 dict of class 9 1045 4 83600 3 2899624 87 __builtin__.wrapper_descriptor <90 more rows. Type eg '_.more' to view.> 

Y:

 >>> hp.iso(1, [1], "1", (1,), {1:1}, None) Partition of a set of 6 objects. Total size = 560 bytes. Index Count % Size % Cumulative % Kind (class / dict of class) 0 1 17 280 50 280 50 dict (no owner) 1 1 17 136 24 416 74 list 2 1 17 64 11 480 86 tuple 3 1 17 40 7 520 93 str 4 1 17 24 4 544 97 int 5 1 17 16 3 560 100 types.NoneType 

Cuando usa la función incorporada dir ([objeto]), puede la función incorporada sizeof .

 >>> a = -1 >>> a.__sizeof__() 24