Cómo reducir el uso de memoria de secuencias de comandos de Python

Tengo un script de python muy grande, 200K, que me gustaría usar la menor cantidad de memoria posible. Se ve algo como:

# a lot of data structures
r = [34, 78, 43, 12, 99]

# a lot of functions that I use all the time
def func1(word):
    return len(word) + 2

# a lot of functions that I rarely use
def func1(word):
    return len(word) + 2


# my main loop
while 1:
   # lots of code
   # calls functions

Si coloco las funciones que rara vez uso en un módulo y las importo dinámicamente solo si es necesario, no puedo acceder a los datos. Eso es todo lo que he conseguido.

Soy nuevo en python.

¿Alguien puede ponerme en el camino correcto? ¿Cómo puedo dividir este gran script para que use menos memoria? ¿Vale la pena poner código rara vez usado en módulos y llamarlos solo cuando sea necesario?

preguntado el 12 de junio de 12 a las 19:06

¿Estás seguro de que usa demasiado ¿memoria? -

Recuerda que “La optimización prematura es la raíz de todos los males”. -

en términos de su problema de funciones, ¿ha verificado si sus funciones se refieren a variables globales? Si lo son (y presumiblemente los datos no están definidos in ese módulo) podría: 1. agregar un parámetro a cada función para tomar cualquier variable global o 2. definir todas las funciones dentro de una clase y pasar las variables globales a __init__ y reescribir las funciones para llamar a los globales como self.<variable name> -

Si su archivo de secuencia de comandos es tan grande, entonces parece que está usando nombres extremadamente variables en todas partes y tiene muchos comentarios en el código, o es más probable que esté haciendo algo muy mal o, en el mejor de los casos, de manera ineficiente. Desafortunadamente, es dudoso que alguien pueda brindarle mucha ayuda basándose solo en la vaga descripción que ha dado de su código. ¡Es hora de ser específico (y aceptar algunas respuestas)! -

5 Respuestas

Organizando:

Su secuencia de comandos de python parece ser enorme, tal vez debería considerar reorganizar su código primero, para dividirlo en varios módulos o paquetes. Probablemente facilitará la creación de perfiles de código y las tareas de optimización.

Es posible que desee echar un vistazo allí:

Y posiblemente:

Optimización:

Hay muchas cosas que se pueden hacer para optimizar su código...

Por ejemplo, con respecto a sus estructuras de datos... Si hace un gran uso de listas o listas de comprensión, podría intentar averiguar dónde realmente necesita listas y dónde podrían ser reemplazadas por estructuras de datos no mutables como tuplas o por Objetos "volátiles", contenedores "perezosos", como expresiones generadoras.

Ver:

En estas páginas, puede encontrar información útil y consejos:

Además, debe estudiar sus formas de hacer las cosas y preguntarse si hay una forma de hacerlo con menos avaricia, una forma en la que sea mejor hacerlo en Python (encontrará algunos consejos en la etiqueta pitónico) ... Eso es especialmente cierto en Python, ya que, en Python, a menudo hay una manera "obvia" (y sólo uno) para hacer cosas que son mejores que las otras (ver El zen de pitón), que se dice que es pitónico. No está especialmente relacionado con la forma de su código, sino también, y sobre todo, con las actuaciones. A diferencia de muchos lenguajes, que promueven la idea de que debería haber muchas formas de hacer cualquier cosa, Python prefiere centrarse solo en la mejor forma. Obviamente, hay muchas maneras de hacer algo, pero a menudo, una es democracia mejor.

Ahora, también debe verificar si está utilizando los mejores métodos para hacer las cosas porque la pitonicidad no organizará sus algoritmos por usted.

Pero al final, varía según tu código y es difícil responder sin haberlo visto.

Y, asegúrese de tener en cuenta los comentarios realizados por eumiro y Amr.

contestado el 05 de mayo de 21 a las 05:05

¿Conoce alguna buena forma de determinar la cantidad de memoria que requiere un fragmento de código de Python? es fácil de usar timeit para comparaciones de velocidad, así que estoy buscando algo que me permita determinar/caracterizar el consumo de memoria. Sólo curiosidad si hay algo tan simple. - Levon

perfil_memoria es bastante útil, fácil de usar para una depuración rápida. ahora puedes probar melias (como hacerlo paso a paso), o abultado para soluciones más completas. buena discusión aquí y algunos métodos de estimación interesantes aquí - cedbeu

Creo que buscas más algo como el perfil_memoria módulo que mencioné, sin embargo. - cedbeu

Gracias por la información, favorecí esta pregunta para poder volver a ella y hacer un seguimiento de los enlaces que mencionaste. Muy apreciado. - Levon

Respondido el 18 de junio de 15 a las 21:06

Los consejos sobre generadores de expresiones y uso de módulos son buenos. La optimización prematura causa problemas, pero siempre debe dedicar unos minutos a pensar en su diseño antes de sentarse a escribir el código. Particularmente si ese código está destinado a ser reutilizado.

Por cierto, menciona que tiene muchas estructuras de datos definidas en la parte superior de su secuencia de comandos, lo que implica que todas están cargadas en la memoria al principio. Si se trata de un conjunto de datos muy grande, considere mover conjuntos de datos específicos a archivos separados y cargarlos solo cuando sea necesario. (utilizando el csv módulo, o numpy.loadtxt(), Etc)

Aparte de usar menos memoria, también busque formas de usar la memoria de manera más eficiente. Por ejemplo, para grandes conjuntos de datos numéricos, las matrices numpy son una forma de almacenar información que proporcionará un mejor rendimiento en sus cálculos. Hay algunos consejos un poco anticuados en http://wiki.python.org/moin/PythonSpeed/PerformanceTips

Respondido el 12 de junio de 12 a las 20:06

Mover funciones no cambiará el uso de la memoria. Tan pronto como importe ese otro módulo, definirá todas las funciones en el módulo. Pero las funciones no ocupan mucha memoria. ¿Son extremadamente repetitivos, quizás pueda tener menos código al refactorizar las funciones?

La pregunta de @eumiro es correcta: ¿estás seguro de que tu script usa demasiada memoria? ¿Cuánta memoria utiliza y por qué es demasiada?

Respondido el 12 de junio de 12 a las 19:06

Si está aprovechando OOP y tiene algunos objetos, diga:

class foo:
    def __init__(self, lorem, ipsum):
        self.lorem = lorem
        self.ipsum = ipsum
    # some happy little methods

Puede hacer que el objeto ocupe menos memoria poniendo:

__slots__ = ("lorem", "ipsum")

justo antes de la __init__ función, como se muestra:

class foo:
    def __init__(self, lorem, ipsum):
        self.lorem = lorem
        self.ipsum = ipsum
    # some happy little methods

Eso sí, “la optimización prematura es la raíz de todos los males”. También perfile el uso de memoria antes y después de la adición para ver si realmente hace algo. Tenga cuidado con descifrar el código (shcokingly) con el entendimiento de que esto podría terminar sin funcionar.

contestado el 07 de mayo de 19 a las 23:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.