Perfile un código de Python línea por línea

Hafiz Muhammad Zohaib 15 febrero 2024
  1. ¿Qué es la elaboración de perfiles?
  2. Perfile el código de Python usando el módulo line_profiler
  3. Perfile el código de Python a través de la línea de comandos
Perfile un código de Python línea por línea

Este artículo explica cómo alguien puede perfilar el código de Python línea por línea y obtener información útil sobre la ejecución del código.

Primero, presentaremos brevemente la elaboración de perfiles; luego, discutiremos cuándo es mejor usar el perfilado línea por línea que el perfilado basado en funciones. Después de eso, discutiremos la implementación de perfiles en Python.

¿Qué es la elaboración de perfiles?

La creación de perfiles es el proceso de verificar los recursos utilizados por diferentes partes de nuestro código. Para prácticas de codificación eficientes, generalmente nos preocupamos principalmente por la complejidad del tiempo (el tiempo que toman las diferentes unidades/funciones de codificación) o la complejidad de la memoria (utilización de la memoria por diferentes unidades/funciones de codificación).

El primero nos ayuda a centrarnos en reducir el tiempo que tarda el programa, y el segundo nos ayuda a optimizar el uso de la memoria.

Perfilado de funciones

Principalmente en cualquier idioma, la creación de perfiles de nivel de función se utiliza para averiguar el tiempo consumido por las diferentes funciones del programa. Por lo tanto, el paquete predeterminado de Python ya incluye las bibliotecas cProfile y Profile para la creación de perfiles de funciones.

Perfilador de línea

El generador de perfiles basado en funciones proporciona información sobre el tiempo que tardan las diferentes funciones. Sin embargo, a veces necesitamos una complejidad de tiempo basada en líneas para verificar qué línea contribuye más al tiempo total que toma la función o el programa.

Tenemos la librería line_profiler en Python para tal caso.

Perfile el código de Python usando el módulo line_profiler

El módulo LineProfiler nos permite perfilar el código línea por línea o por función.

En el siguiente fragmento de código de Python, hemos creado dos funciones denominadas slow_avg_producer() y fast_average_producer(). Ambas funciones producen el mismo promedio, pero su tiempo de ejecución es diferente.

Primero, instale el siguiente módulo para perfilar el código usando el perfilador de línea.

!pip install line_profiler
import time
import random


def slow_avg_producer():
    time.sleep(6)  # Do nothing for 5 time units
    # generate random numbers array
    arr = [
        random.randint(1, 100) for i in range(10000)
    ]  # generate random numbers array
    return sum(arr) / len(arr)


def fast_average_producer():
    time.sleep(1)  # Do nothing for 1 time units
    # generate random numbers array
    arr = [random.randint(1, 100) for i in range(10000)]
    return sum(arr) / len(arr)


def main_func():
    average = slow_avg_producer()
    print(average)

    result = fast_average_producer()
    print(average)

Para obtener las estadísticas de tiempo, primero creamos el objeto LineProfiler y luego se pasa main_func() para obtener el contenedor. Al final, podemos obtener las estadísticas de perfilado.

from line_profiler import LineProfiler

line_prof = LineProfiler()
line_prof_wrapper = line_prof(main_func)
line_prof_wrapper()
# print the profiling details
line_prof.print_stats()

El código anterior produce el siguiente resultado. La unidad de tiempo es en microsegundos.

Timer unit: 1e-06 s

Total time: 7.10521 s
File: <ipython-input-14-67ae2a9633ee>
Function: main_func at line 17

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
    17                                           def main_func():
    18         1    6054801.0 6054801.0     85.2      average = slow_avg_producer()
    19         1        676.0    676.0      0.0      print(average)
    20
    21         1    1049070.0 1049070.0     14.8      result = fast_average_producer()
    22         1        659.0    659.0      0.0      print(average)

Las estadísticas muestran que en la función principal, el slow_avg_producer() tarda 6,054 segundos y la siguiente sentencia print tarda 0,000676 segundos. Por otro lado, el fast_average_producer() lleva mucho menos tiempo.

Perfile el código de Python a través de la línea de comandos

Podemos usar la interfaz de línea de comandos para obtener los detalles de perfilado de las funciones línea por línea. Para este método, usamos el comando kernprof.

También usaremos las mismas funciones aquí, excepto que agregaremos un decorador, @profile, al comienzo de cada función. Llamamos a este script promedio_productor.py.

import time
import random


@profile
def slow_avg_producer():
    time.sleep(6)  # Do nothing for 5 time units
    # generate random numbers array
    arr = [
        random.randint(1, 100) for i in range(10000)
    ]  # generate random numbers array
    return sum(arr) / len(arr)


@profile
def fast_average_producer():
    time.sleep(1)  # Do nothing for 1 time units
    # generate random numbers array
    arr = [random.randint(1, 100) for i in range(10000)]
    return sum(arr) / len(arr)


@profile
def main_func():
    average = slow_avg_producer()
    print(average)

    result = fast_average_producer()
    print(average)


main_func()

Usando el comando kernprof, necesitamos instalar el módulo line-profiler usando el siguiente comando.

pip install line-profiler

Para el terminal Colab o Jupyter Notebook, use el símbolo de explosión (!) al comienzo del comando anterior.

instalar el perfilador de línea

Después de la instalación, debe cambiar el directorio donde está instalado kernprof.exe. Luego ejecute el siguiente comando.

kernprof nos da la opción de hacer cProfile, pero aquí usamos el perfilador de líneas. Para eso, se usa el argumento -l.

kernprof -l average_producer.py

kernprof

Ejecute el siguiente comando para ver los resultados de la creación de perfiles.

python -m line_profiler average_producer.py.lprof

Imprime los resultados de la creación de perfiles en la interfaz de línea de comandos, como se muestra a continuación.

perfilador de línea de python

resultados de perfiles

Artículo relacionado - Python Profile