Perfilado
¿Por dónde empezar?
En las aplicaciones modernas, que a menudo se dividen en multitud de proyectos, a veces es difícil saber por dónde empezar nuestro análisis de rendimiento. Si se ha identificado un escenario específico, es necesario reproducirlo localmente para poder determinar en qué momento se produce el cuello de botella y, por tanto, identificar el proyecto o proyectos implicados.
Sin embargo, como ya se ha dicho, la optimización del rendimiento debe integrarse en el proceso normal de escritura de una funcionalidad. Y normalmente, en este punto, no ha surgido ningún escenario concreto. Esto hace que sea más difícil saber por dónde empezar.
Un enfoque sería poner tantos perfiladores como sea necesario en cada proyecto relacionado con la funcionalidad para averiguar de dónde pueden venir las ralentizaciones. Al elegir este enfoque, el sistema en su conjunto se vería demorado por los perfiladores y, por tanto, podría dar lugar a la detección de falsos positivos.
En el caso de una arquitectura moderna, con un front-end (apariencia de la aplicación para el usuario) y un back-end (lógica detrás del escenario para que la interfaz funcione), la cuestión del rendimiento bruto suele abordarse casi exclusivamente en el back-end. De hecho, la sensación de rendimiento puede simularse mediante subterfugios dentro del front-end...
Escenarios de perfilado
Como ya se ha explicado en el primer capítulo, es importante basarse en escenarios bien definidos en los que queremos mejorar el rendimiento. Se prepararán dos escenarios, con el objetivo de mejorar el tiempo empleado en cada uno de ellos, pero también para limitar los recursos consumidos.
Dada la baja complejidad de la aplicación de demostración, estos dos escenarios cubren casi todas las interacciones disponibles.
1. Primer escenario: mostrar los datos de una persona
Para este primer escenario, se realizarán una serie de interacciones sencillas. Comenzaremos por iniciar la sesión:
Etapa de conexión
El sistema de autenticación es muy sencillo: consiste en invertir el orden de las letras del nombre de usuario para obtener la contraseña. Así, el usuario «admin» tendrá la contraseña «nimda». Esto funciona para todos los usuarios, ya que no existe ninguna tabla de usuarios.
La forma en que se realiza la autenticación no respeta ninguna buena práctica de seguridad. Así, se crea un rastreador (cookie) en la aplicación, con la clave «Authenticated» que contiene el valor «true», indicando que el usuario está autentificado. Esto está muy lejos de lo que se recomienda para proteger una aplicación de Blazor y solo está presente para fines de demostración simplificada....
Ejecutar un perfilado
Con la ayuda de los escenarios seleccionados anteriormente, ahora se puede poner en marcha de forma efectiva el perfilado.
Ejecute la solución Profi (a partir del directorio AntesDeLaOptimizacion o donde lo copió) en Visual Studio 2022 para comenzar la investigación. El primer paso será perfilar el consumo de memoria y la CPU de la API a medida que se ejecutan los escenarios. Para ello, la instancia de Visual Studio 2022 se dedicará a esta supervisión.
1. Perfilar la API: primer escenario
Se empezará por perfilar la API para investigar las pérdidas de rendimiento en bruto, independientemente del cliente utilizado.
En primer lugar, se debe asegurar de que el proyecto de inicio es Profi.API (1) y que el modo de compilación es, por supuesto, Release (2). Esta información suele encontrarse en la barra de herramientas de Visual Studio 2022:
Barra de herramientas de Visual Studio
Si todo está configurado correctamente, se puede empezar a configurar la sesión de perfilado, abriendo el menú de Depurar (1) y seleccionando luego Generador de perfiles de rendimiento (2). Esto también puede hacerse utilizando el método abreviado predefinido [Alt][F2].
Menú para ejecutar el perfilador
Cuando se ejecuta la configuración del perfilador, solo se selecciona comprobar una métrica: Uso de CPU.
Configuración de la sesión de perfilado
Se debe asegurar de que el objetivo sea Profi.API. Si no es así, simplemente se utiliza el menú superior izquierdo para seleccionar Cambiar objetivo y elegir Proyecto de inicio. Antes de empezar a perfilar, y para evitar la pérdida de tiempo, se recomienda ejecutar directamente el proyecto del cliente. Para ello, se abre un símbolo del sistema en el directorio del proyecto Profi.Client, al mismo nivel que el archivo csproj, y se usa el siguiente comando:
dotnet run
El cliente se ejecuta en la consola (se puede hacer [Ctrl] + clic en el vínculo para abrir directamente el programa en el navegador predefinido).
a. Ejecutar con el perfilador
Antes de iniciar de forma efectiva el perfilado, se debe indicar la forma correcta de realizar una sesión de perfilado. Esto se hace de forma iterativa respectando los siguientes pasos:
-
Inicie la sesión, ejecute el escenario y analice los resultados. El objetivo de la herramienta es controlar...
Conclusión
Hemos terminado de optimizar la parte del servidor de nuestro sistema, y en este capítulo hemos visto cómo analizar los resultados para sacar las conclusiones oportunas.
Por supuesto, las cifras serán únicas para cada entorno de ejecución, por lo que las publicadas anteriormente son puramente ilustrativas. En cuanto consideremos que la ganancia de rendimiento es lo suficientemente significativa, debemos detener el proceso de perfilado y optimización.
Como se ha dicho al principio de este libro, el objetivo no es hacer tuning y ahorrar unos milisegundos, sino optimizar para ganar el suficiente rendimiento para que lo perciba el usuario. Al final, si queremos resumir el resultado de nuestra sesión, podemos ver que:
-
La mala gestión de la conexión SQL en el primer escenario nos estaba costando mucho y nos hacía limitar el procesamiento a un máximo de 50 consultas en 30 segundos. La corrección de este error nos ha permitido alcanzar más de 7.000 consultas en el mismo periodo de tiempo.
-
La gestión de la fusión de contratos era costosa debido al acceso al sistema de archivos, y cuando cambiamos exclusivamente a la memoria (porque el benchmark nos demostró que esto era más eficiente), la presión sobre el GC aumentó e implementamos técnicas avanzadas, lo que nos permitió procesar hasta casi 400 fusiones...