Utilice estos consejos para analizar su código y descubrir dónde es más o menos eficiente.

Dado que "hay más de una forma de hacerlo" en Python, encontrar el enfoque más eficiente en memoria para algunas tareas puede ser un desafío. Aquí es donde un generador de perfiles de memoria puede ayudar. Además de rastrear las fugas, estimar el perfil de memoria de su código ayuda a determinar qué código es eficiente en términos de memoria.

Ya sea que esté desarrollando un modelo de aprendizaje automático o un sitio web con Python, puede estimar el perfil de memoria para scripts, líneas de código individuales o funciones.

Estimar el perfil de memoria de toda su base de código puede no ser práctico, ya que esto puede ralentizar significativamente su aplicación. Es mejor que perfile funciones o métodos de forma selectiva que sospeche que podrían estar consumiendo más memoria. Pero incluso si desea hacer esto para toda su aplicación, es posible que desee dedicar un módulo aislado para manejarlo.

Hay muchas bibliotecas de creación de perfiles en Python. Algunos de los más populares son

instagram viewer
Perfilador de memoria, psutil, Tracemalloc, y Pympler. Este tutorial utiliza Perfilador de memoria y psutil.

Mientras psutil es ideal para estimar el consumo total de memoria de la ejecución de un método o función, Perfilador de memoria brinda información más detallada sobre el uso de la memoria, incluidas las tendencias de uso de nivel funcional y línea por línea a lo largo del tiempo.

Para empezar, instala Perfilador de memoria en su entorno virtual de Python. Esto también instala psutil.

pip instalar perfil_memoria

Obtener el tamaño de un objeto en la memoria

Puede comenzar su perfil de memoria calculando primero el tamaño de un objeto que pretende usar en la memoria.

Este tipo de creación de perfiles es útil al comienzo del desarrollo, al intentar determinar qué tipo de objeto usar en un programa.

Por ejemplo, si te quedas atascado decidiendo qué métodos usar para lograr una tarea, digamos, el apropiado Tipo de datos de Python, puede obtener el tamaño de cada uno en bytes para determinar cuál es más liviano para su uso caso.

El sys.getsizeof El método incorporado es útil aquí:

importar sistema
imprimir(f"tamaño de la lista: {sys.getsizeof([])} bytes")
imprimir(f"tamaño del diccionario: {sys.getsizeof (dict)} bytes")
imprimir(tamaño de la tupla f": {sys.getsizeof(())} bytes")
imprimir(f"establecer tamaño: {sys.getsizeof({})} bytes")

Aquí está la salida:

También puede utilizar el sys.getsizeof método para comparar el tamaño de la memoria de una función integrada y personalizada.

Por ejemplo, compare esta función de longitud personalizada que usa un bucle for de Python con el incorporado Len función:

importar sistema

definitivamenteobtenerLongitud(iterable):
contar = 0

para i en iterable:
contar +=1

devolver contar

imprimir(f"Función de longitud incorporada: {sys.getsizeof (largo)} bytes")
imprimir(f"Función de longitud personalizada: {sys.getsizeof (getLength)} bytes")

El código anterior da el siguiente resultado:

Sin embargo, mientras sys.getsizeof mide el tamaño de un objeto en la memoria, solo da cuenta del objeto en sí y no de los que hacen referencia a él. Para eso, necesitará un método de perfilado más detallado.

Encuentre el perfil de memoria de una función de Python

Puede obtener un perfil de memoria más detallado de cada línea de código de una función usando el Perfilador de memoria paquete. Esto implica agregar la @perfil decorador a su función o método:

importar pandas
importar numpy
desde memory_profiler importar perfil

clase manipular:
@perfil
def manipularData (auto):
df = pandas. Marco de datos({
'A' :[0, 3, numpy.nan, 10, 3, numpy.nan],
'B': [numpy.nan, "Pandas", numpy.nan, "Pandas", "Python", "JavaScript"],
})

df.fillna (método='bfill', inplace=True)
df.fillna (método='rellenar', inplace=True)
retorno str (df)

manip = Manipular()
imprimir (manip.manipulateData())

El código anterior proporciona un perfil de memoria detallado de cada línea de código en la función como se muestra:

El uso de memoria columna indica el uso de memoria para una línea de código en particular, mientras que la Incremento columna muestra los gastos generales aportados por cada línea. El Ocurrencia La columna define el número de veces que una línea de código asigna o desasigna memoria.

Por ejemplo, en el resultado anterior, la línea 11 se produjo dos veces con un incremento de memoria de 0,1 MiB (Mebibyte), aumentando el uso de memoria a 55,4 MiB. Las líneas 19 y 22 también aportaron 0,2 MiB y 0,3 MiB, respectivamente, totalizando el uso de memoria en 55,9 MiB.

Encuentre el perfil de memoria de un script de Python por marca de tiempo

También puede estimar el perfil de memoria de un script completo de Python usando el Perfilador de memoria ejecutando el mprof Comando en la terminal como se muestra:

mprof ejecutar script_name.py

El comando anterior muestra el script especificado cada 0,1 s y crea automáticamente un .dat archivo dentro de su directorio de proyecto actual.

Las cifras que siguen a la MEM notación son los perfiles de uso de memoria de la secuencia de comandos de Python en un intervalo de tiempo específico. Las últimas cifras a la derecha representan la marca de tiempo que capturó el generador de perfiles para cada uso de memoria.

También puede obtener un gráfico del perfil de memoria. Esto requiere una instalación de matplotlib:

pip instalar matplotlib

Una vez instalado, ejecute el mprof comando así:

trama mprof

Aquí está la salida en este caso:

Ejecute el perfil de memoria de secuencias de comandos en un archivo de Python dedicado

Es posible que desee crear un perfil para diferentes secuencias de comandos de Python. Puedes hacerlo usando un módulo de Python dedicado a través de Python subproceso.

De esta forma, puede separar su generador de perfiles de memoria de su base de código y guardar la salida del gráfico localmente:

importar subproceso

subproceso.ejecutar([
'mprof', 'correr', '--incluir-niños', 'missing.py'
])

# guardar la salida de la trama localmente
subproceso.ejecutar(['mprof', 'trama', '--salida=salida.jpg'])

Para ejecutar el perfil de memoria del script, solo necesita ejecutar el archivo de Python que contiene el código anterior. Esto genera un gráfico de perfil de memoria (salida.jpg) en el directorio de archivos:

Encuentre la cantidad de memoria utilizada a partir de la ejecución de una función

Puede encontrar el perfil de memoria total de un método o función durante la ejecución usando el psutil paquete.

Por ejemplo, para perfilar el anterior Manipulación de Pandas DataFrame método dentro de otro archivo de Python:

importar psutil
importar sistema
importar sistema operativo
sys.ruta.append (sys.ruta[0] + "/..")

# importa la clase que contiene tu método
de algún código.falta importar Manipular

# instanciar la clase
manip = Manipular()

proceso = psutil. Proceso (os.getpid())
memoria_inicial = proceso.memoria_info().rss

# ejecutar el método de destino:
manip.manipulateData()

# obtener la información de la memoria después de la ejecución
memoria_final = proceso.info_memoria().rss
memoria_consumida = memoria_final - memoria_inicial
memory_consumed_mb = memory_consumed / (1024 * 1024)
imprimir(f"Memoria consumida por la función: {memoria_consumida_mb:.2F} MEGABYTE")

Lo anterior estima el perfil de memoria total del método en megabytes (MB) como se muestra:

Encuentre el perfil de memoria de una línea de código en Jupyter Notebook

Si usa iPython en Jupyter Notebook, puede calcular el perfil de memoria de una sola línea usando el Perfilador de memoria. Solo necesitas cargar Perfilador de memoria en una celda. Luego agrega el %recuerda función mágica a su código en celdas posteriores; esto devuelve la memoria máxima del código y el tamaño incrementado.

Este método no funciona con secuencias de comandos de Python normales además de iPython en Jupyter Notebook.

Por ejemplo:

También puede utilizar el %recuerda función mágica en Jypyter Notebook para perfilar la memoria de una función en tiempo de ejecución:

Mejore la eficiencia de su memoria en su código Python

Teniendo en cuenta las tareas pesadas de levantamiento de datos para las que a menudo usamos Python, cada línea de código necesita una optimización adecuada para administrar el uso de la memoria. Si bien Python presenta muchas funciones integradas de Python, los objetos sin referencia dan como resultado pérdidas de memoria.

Si ha estado eliminando todas las sintaxis de Python que funcionan en su base de código sin considerar el uso de la memoria, es posible que desee mirar hacia atrás antes de ir demasiado lejos.