Necesito optimizar el uso de RAM de mi aplicación.
POR FAVOR, evíteme las conferencias diciéndome que no me debería importar la memoria al codificar Python. Tengo un problema de memoria porque uso diccionarios predeterminados muy grandes (sí, también quiero ser rápido). Mi consumo de memoria actual es de 350 MB y está creciendo. Ya no puedo usar el alojamiento compartido y si mi Apache abre más procesos, la memoria se duplicará y triplicará ... y es costoso.
He hecho perfiles extensos y sé exactamente dónde están mis problemas.
Tengo varios diccionarios grandes (> 100 000 entradas) con claves Unicode. Un diccionario comienza en 140 bytes y crece rápidamente, pero el problema más grande es las claves. Python optimiza las cadenas en la memoria (o eso he leído) para que las búsquedas puedan ser comparaciones de ID ('interning'). No estoy seguro de que esto también sea cierto para las cadenas Unicode (no pude 'internarlas').
Los objetos almacenados en el diccionario son listas de tuplas (un_objeto, un int, un int).Python consejos para la optimización de la memoria
my_big_dict [some_unicode_string] .Append ((mi_objeto, an_int, another_int))
que ya encontraron que vale la pena para dividir a varios diccionarios porque las tuplas toman mucho espacio .. .
¡Descubrí que podía ahorrar memoria RAM mezclando las cadenas antes de usarlas como claves! Pero luego, por desgracia, me encontré con colisiones de cumpleaños en mi sistema de 32 bits. (Pregunta lateral: ¿hay un diccionario de teclas de 64 bits que pueda usar en un sistema de 32 bits?)
Python 2.6.5 en Linux (producción) y Windows. ¿Algún consejo sobre la optimización del uso de memoria de diccionarios/listas/tuplas? Incluso pensé en usar C - No me importa si este pequeño fragmento de código es feo. Es solo un lugar singular.
¡Gracias de antemano!
2 pequeños comentarios: me gustan mucho las respuestas listas para usar del sistema, pero ¿pueden (por ejemplo, una base de datos, incluso en caché) comparar realmente el rendimiento con un diccionario de Python? Estoy ejecutando algoritmos en tiempo real y el diccionario es apenas lo suficientemente rápido. Ciertamente probaré Memcached y Redis (genial) pero ¿las comunicaciones entre procesos serán lo suficientemente rápidas para mí? (Lo siento por agregar esto ahora. Difícil de optimizar tanto para la memoria como para la velocidad ...) Además, mi diccionario es principalmente de solo lectura. ¿Puedo usar este conocimiento de alguna manera? –
"PEP 412: Key-Sharing Dictionary" puede ser de su interés. Creo que está incluido en Python 3.3 http://www.python.org/dev/peps/pep-0412/ – bcoughlan
@bcoughlan muy genial, gracias! Lamentablemente, tengo que esperar un 2.7 backport. –