Buenas Prácticas de Rendimiento
Reglas de rendimiento que evitan la optimización prematura y centran el esfuerzo en los cuellos de botella medidos.
Cómo Usar Esta Lista
- Postura por defecto: legibilidad sobre micro-optimización
- Rompe estas reglas solo con datos de perfil que demuestren el punto crítico
- Documenta cada optimización con números de antes y después
A - Medición
- Perfila antes de optimizar. cProfile, py-spy o APM - nunca adivines.
- Define el SLA antes de ajustar. Conoce la latencia p95 o el rendimiento objetivo.
- Evalúa cargas de trabajo realistas. Tamaños de datos de producción y concurrencia.
- Registra números de antes y después. Cada optimización necesita pruebas.
B - Algoritmo y Datos
- Algoritmo correcto primero. O(n log n) supera a O(n^2) micro-optimizado.
- Vectoriza bucles numéricos. NumPy/Polars para operaciones de arrays y DataFrames.
- Procesa datos grandes en streaming. Generadores sobre listas materializadas.
- Estructura de datos correcta.
setpara pertenencia,dequepara colas,dictpara búsqueda.
C - Concurrencia
-
asynciopara I/O-bound.httpx,asyncpg,aiofiles. -
multiprocessingpara CPU-bound. No hilos (GIL). - Limita la concurrencia. Semáforos y límites de pool evitan la sobrecarga.
- No bloquees en manejadores
async. Usaasyncio.to_threadpara código bloqueante heredado.
D - Caché y E/S
- Caché con límites.
maxsizeyTTLen cada caché. - Pooling de conexiones. Reutiliza conexiones de BD y HTTP.
- Agrupa operaciones de E/S. Inserciones masivas, recopila peticiones HTTP.
- Serialización eficiente.
orjsonpara rutas JSON críticas.
E - Cuándo Parar
- ¿SLA cumplido? Deja de optimizar. El trabajo adicional tiene rendimientos decrecientes.
- Legibilidad conservada. La optimización compleja necesita comentarios que expliquen el porqué.
- Las pruebas siguen pasando. Corrección antes que velocidad.
- No a Cython/Rust prematuro. Python es lo suficientemente rápido hasta que se demuestre lo contrario con perfilado.
Preguntas Frecuentes
¿Es Python lento?
Python es lo suficientemente rápido para la mayoría de cargas de trabajo web y de datos. Optimiza los puntos críticos, no el lenguaje.
¿Debería usar PyPy?
Solo si las evaluaciones comparativas en tu carga de trabajo específica muestran claras ventajas.
¿Comprensión de listas o map?
Legibilidad primero. Perfila si es crítico. Las diferencias suelen ser insignificantes.
¿Cuándo usar Cython?
Cuando un punto crítico perfilado no se puede arreglar con NumPy, mejores algoritmos o caché.
¿Cómo evito la regresión de rendimiento?
Evalúa los caminos críticos en CI con pytest-benchmark. Alerta ante el incumplimiento de umbrales.
¿`asyncio` en todas partes?
No. Solo servicios I/O-bound que se benefician de la concurrencia. Añade complejidad.
¿Qué pasa con el rendimiento de la base de datos?
Los índices, los planes de consulta y la eliminación de N+1 a menudo superan al ajuste a nivel de aplicación.
¿Debería usar `__slots__`?
Para millones de objetos pequeños con atributos fijos. No por defecto.
¿Cómo establezco presupuestos de rendimiento?
Define la latencia p95 por endpoint. Bloquea despliegues que excedan el presupuesto en pruebas de carga.
¿Micro-optimizar la concatenación de cadenas?
Solo en bucles críticos perfilados. Las f-strings están bien para código normal.
Relacionado
- Conceptos Básicos de Rendimiento - primeros pasos
- Lista de Verificación de Auditoría de Rendimiento - revisión sistemática
- cProfile y Profilers - encontrando puntos críticos
- Async y Concurrencia para Rendimiento - paralelismo
Versiones de la pila: Esta página fue escrita para Python 3.14.0, FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.