Pregunta

Por ejemplo, ¿cuánta memoria se necesita para almacenar una lista de un millón de enteros (32 bits)?

alist = range(1000000) # or list(range(1000000)) in Python 3.0
¿Fue útil?

Solución 2

Enlaces útiles:

Cómo obtener el tamaño de la memoria / el uso del objeto python

¿Tamaños de memoria de los objetos de python?

si coloca los datos en el diccionario, ¿cómo calculamos el tamaño de los datos? ?

Sin embargo no dan una respuesta definitiva. El camino a seguir:

  1. Mida la memoria consumida por el intérprete de Python con / sin la lista (use las herramientas del sistema operativo).

  2. Use un módulo de extensión de terceros que defina algún tipo de tamaño (PyObject).

Actualizar :

Receta 546530: Tamaño de los objetos de Python (revisado)

import asizeof

N = 1000000
print asizeof.asizeof(range(N)) / N
# -> 20 (python 2.5, WinXP, 32-bit Linux)
# -> 33 (64-bit Linux)

Otros consejos

" Depende. " Python asigna espacio para las listas de tal forma que logre tiempo constante amortizado para agregar elementos a la lista.

En la práctica, lo que esto significa con la implementación actual es ... la lista siempre tiene espacio asignado para un número de poder de dos elementos. Entonces, el rango (1000000) asignará una lista lo suficientemente grande como para contener 2 ^ 20 elementos (~ 1.045 millones).

Este es solo el espacio requerido para almacenar la estructura de la lista (que es una matriz de punteros a los objetos de Python para cada elemento). Un sistema de 32 bits requerirá 4 bytes por elemento, un sistema de 64 bits utilizará 8 bytes por elemento.

Además, necesita espacio para almacenar los elementos reales. Esto varía ampliamente. Para los enteros pequeños (de -5 a 256 actualmente), no se necesita espacio adicional, pero para números más grandes, Python asigna un nuevo objeto para cada entero, que toma de 10 a 100 bytes y tiende a fragmentar la memoria.

Línea inferior: es complicado y las listas de Python no son una buena manera de almacenar grandes estructuras de datos homogéneas. Para eso, use el módulo array o, si necesita hacer cálculos vectorizados, use NumPy.

PS- Las tuplas, a diferencia de las listas, no están diseñadas para tener elementos agregados progresivamente a ellas. No sé cómo funciona el asignador, pero ni siquiera piense en usarlo para grandes estructuras de datos :-)

Direccionamiento " tupla " parte de la pregunta

La declaración de PyTuple de CPython en una configuración de construcción típica se reduce a esto:

struct PyTuple {
  size_t refcount; // tuple's reference count
  typeobject *type; // tuple type object
  size_t n_items; // number of items in tuple
  PyObject *items[1]; // contains space for n_items elements
};

El tamaño de la instancia de PyTuple se fija durante su construcción y no se puede cambiar posteriormente. El número de bytes ocupados por PyTuple se puede calcular como

  

sizeof (size_t) x 2 + sizeof (void *) x (n_items + 1) .

Esto le da a poca profundidad el tamaño de la tupla. Para obtener el tamaño completo , también debe agregar la cantidad total de bytes consumidos por el gráfico de objetos enraizado en la matriz PyTuple :: items [] .

Vale la pena señalar que las rutinas de construcción de tuplas aseguran que solo se cree una única instancia de tupla vacía (singleton).

Referencias: Python.h , object.h , tupleobject.h , tupleobject.c

  

Una nueva función, getsizeof () , toma una   Objeto de Python y devuelve la cantidad.   de memoria utilizada por el objeto, medida   en bytes. Devolución de objetos incorporados   resultados correctos tercero   Las extensiones pueden no, pero pueden definir un   Método __sizeof __ () para devolver el tamaño del objeto.

kveretennicov@nosignal:~/py/r26rc2$ ./python
Python 2.6rc2 (r26rc2:66712, Sep  2 2008, 13:11:55) 
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
>>> import sys
>>> sys.getsizeof(range(1000000))
4000032
>>> sys.getsizeof(tuple(range(1000000)))
4000024

Los números devueltos obviamente no incluyen la memoria consumida por los objetos contenidos (sys.getsizeof (1) == 12).

Esta es una implementación específica, estoy bastante seguro. Ciertamente, depende de la representación interna de los enteros: no puede suponer que se almacenarán como de 32 bits ya que Python le proporciona enteros arbitrariamente grandes, por lo que tal vez las pequeñas entradas se almacenen de manera más compacta.

En mi Python (2.5.1 en Fedora 9 en core 2 duo), el VmSize antes de la asignación es 6896kB, después es 22684kB. Después de un millón más de asignación de elementos, VmSize va a 38340kB. Esto indica en gran medida alrededor de 16000 kB para 1000000 enteros, que es de alrededor de 16 bytes por entero. Eso sugiere un lote de sobrecarga para la lista. Tomaría estos números con una gran pizca de sal.

Desconfío de por qué lo preguntas. ¿Está tratando de averiguar cuánta memoria necesitará para una implementación determinada? Digamos que vas a leer 10,000,000 de widgets y quieres saber cuánta RAM apestará.

Si ese es el caso, en lugar de tratar de calcular la cantidad de RAM que ocupa cada widget, calcula la cantidad de RAM, por ejemplo, 10,000 widgets y multiplica para obtener tu tamaño real.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top