Perfilado con cProfile y line_profiler
Encuentre los puntos críticos de CPU con cProfile y el perfilado línea por línea.
Perfilado con cProfile y line_profiler es una lección gratuita de Python Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Python Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Python Academy incluye 4 lecciones en total.
¿Por qué usar el perfilado?
El perfilado identifica qué funciones consumen más tiempo y orienta los esfuerzos de optimización. Perfile siempre antes de optimizar; nunca adivine.
import cProfile
def slow():
total = 0
for i in range(1_000_000):
total += i
return total
cProfile.run("slow()")Ejecución de cProfile desde la CLI
Perfile un script completo sin modificarlo: python -m cProfile -s cumtime script.py. Ordene los resultados por cumtime, tottime o calls.
# python -m cProfile -s cumtime my_script.py
#
# ncalls tottime percall cumtime percall filename:lineno(function)
# 1000 0.500 0.001 2.100 0.002 utils.py:10(process)cProfile en el código
Cree un cProfile.Profile, actívelo y desactívelo; después, muestre las estadísticas con pstats.
import cProfile, pstats, io
pr = cProfile.Profile()
pr.enable()
# ... code to profile ...
pr.disable()
stream = io.StringIO()
ps = pstats.Stats(pr, stream=stream).sort_stats("cumulative")
ps.print_stats(10) # top 10
print(stream.getvalue())Filtrado con pstats
Filtre la salida del profiler para mostrar únicamente un módulo específico o un patrón de nombre de función mediante print_stats(pattern).
import cProfile, pstats
cProfile.run("my_function()", "profile.out")
stats = pstats.Stats("profile.out")
stats.sort_stats("tottime")
stats.print_stats("mymodule") # only mymodule functionsline_profiler
line_profiler muestra el tiempo de ejecución de cada línea, no solo de cada función; es esencial para encontrar la línea crítica dentro de una función.
# pip install line_profiler
# Decorate target function:
from line_profiler import profile
@profile
def process(data):
result = []
for item in data: # <- which line is slow?
result.append(item*2)
return result
# Run: kernprof -l -v script.pyCLI de kernprof
kernprof -l script.py ejecuta el script con el perfilado por línea activado; -v muestra el informe inmediatamente.
# kernprof -l -v script.py
#
# Line # Hits Time Per Hit % Time Line Contents
# ======================================================
# 4 1 2.0 2.0 1.0 result = []
# 5 1000 120.0 0.1 60.0 for item in data:
# 6 1000 80.0 0.1 39.0 result.append(item*2)Perfilado en Jupyter
Jupyter proporciona los comandos mágicos %prun (cProfile) y %lprun (line_profiler).
# In a Jupyter cell:
# %prun -s cumulative my_function(data)
# %load_ext line_profiler
# %lprun -f my_function my_function(data)Identificación de cuellos de botella
Concéntrese en las funciones con el mayor tiempo acumulado (toda la cadena) y el mayor tiempo total (la propia función, sin incluir las funciones que llama).
# cumtime = total time including callees (find root cause)
# tottime = time in function itself (find where work happens)
#
# Optimise the function with highest tottime firstCómo evitar la optimización prematura
Perfile primero y, después, optimice el cuello de botella medido. Algunas formas habituales de acelerar Python son usar funciones integradas, trasladar los bucles a NumPy, almacenar en caché las búsquedas repetidas o llamar a C mediante ctypes/cffi.
# Before optimising:
# profile shows: process_row() 95% of time
# Speedup: vectorise with NumPy
import numpy as np
arr = np.array(data)
result = arr * 2 # 100x faster than Python looppy-spy: profiler de muestreo
py-spy perfila procesos en ejecución sin modificar el código: conéctelo a un PID activo.
# pip install py-spy
# Profile for 30 s and show flamegraph:
# py-spy top --pid 12345
# py-spy record -o profile.svg --pid 12345 --duration 30Pruebas de rendimiento con timeit
Use timeit para realizar micropruebas de expresiones específicas.
import timeit
result = timeit.timeit(
"[x*2 for x in range(1000)]",
number=10_000
)
print(f"{result:.3f} s for 10k runs")Comprobación rápida
¿Qué muestra tottime en un informe de cProfile?
Resumen
Use cProfile para encontrar funciones lentas y line_profiler para encontrar la línea lenta. Perfile con -s cumtime para encontrar las causas raíz. Optimice únicamente los cuellos de botella comprobados; use la vectorización de NumPy, la caché o extensiones en C para obtener las mayores mejoras.
Preguntas frecuentes
¿La lección «Perfilado con cProfile y line_profiler» es gratis?
Sí — el texto completo de «Perfilado con cProfile y line_profiler» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Python Academy, actualiza a CoddyKit PRO. El curso de Python Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Perfilado con cProfile y line_profiler»?
Encuentre los puntos críticos de CPU con cProfile y el perfilado línea por línea. Practicas Python Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Python Academy?
No se requiere experiencia previa. Python Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.
¿Cuánto tiempo toma la lección «Perfilado con cProfile y line_profiler»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Python Academy?
Sí. Cada lección de Python Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Conteo de referencias en CPython
- El recolector de basura y las referencias cíclicas
- Perfilado con cProfile y line_profiler
- Perfilado de memoria con tracemalloc