Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este caso práctico se muestra cómo usar las herramientas de generación de perfiles de Visual Studio para identificar y resolver problemas de rendimiento en una aplicación de ejemplo ASP.NET. Para obtener una comparación de las herramientas de generación de perfiles, consulte ¿Qué herramienta debo elegir?
Aprenderá lo siguiente:
- Cómo usar las herramientas de generación de perfiles de Visual Studio para analizar el rendimiento de las aplicaciones.
- Cómo interpretar los datos de perfiles para identificar cuellos de botella.
- Estrategias prácticas para optimizar el código mediante contadores de .NET, recuentos de llamadas y datos de tiempo.
Aplique estas técnicas para mejorar sus propias aplicaciones.
Aislar un caso de estudio de problemas de rendimiento
La aplicación ASP.NET de ejemplo ejecuta consultas en una base de datos simulada y se basa en el Diagnostics Sample.
Síntomas clave del rendimiento:
- Bajo uso de CPU: La CPU no es el cuello de botella.
- Recuento elevado de subprocesos de ThreadPool: el recuento de subprocesos aumenta constantemente, lo que indica el colapso del grupo de subprocesos.
- Respuesta lenta de la aplicación: la aplicación responde lentamente debido a la falta de subprocesos disponibles.
En este caso práctico se usan herramientas de generación de perfiles de Visual Studio para identificar y solucionar estos problemas, lo que le ayuda a hacer que el código sea más rápido y eficaz.
Desafío
Solucionar estos problemas implica varios desafíos:
- Diagnosticando cuellos de botella: Un bajo uso de CPU con un rendimiento lento puede tener múltiples causas. El uso eficaz de las herramientas de generación de perfiles y la interpretación de su salida es esencial.
- Conocimientos y restricciones de recursos: la generación de perfiles y la optimización requieren aptitudes y experiencia específicas, lo que puede no estar siempre disponible.
Un enfoque estratégico que combina herramientas de generación de perfiles, conocimientos técnicos y pruebas cuidadosas es clave para superar estos desafíos.
Estrategia
Esta es una vista general del enfoque en este caso práctico:
- Empiece por supervisar las métricas del contador de .NET al recopilar datos de rendimiento. La herramienta Contadores de .NET de Visual Studio es un buen punto de partida.
- Para obtener información más detallada, recopile seguimientos con herramientas de generación de perfiles adicionales, como la herramienta Instrumentación para recuentos de llamadas y datos de tiempo.
La recopilación de datos requiere las siguientes tareas:
- Configure la aplicación como Compilación de versión.
- Seleccione la herramienta Contadores de .NET en Performance Profiler (Alt+F2).
- Inicie la aplicación y recopile una traza.
Comprobación de contadores de rendimiento
Al ejecutar la aplicación, observamos los contadores en la herramienta Contadores de .NET. En el caso de las investigaciones iniciales, se incluyen algunas métricas clave para tener en cuenta:
-
CPU Usage. Vea este contador para ver si se produce un problema de rendimiento con un uso elevado o bajo de cpu. Esto puede ser una pista de los tipos específicos de problemas de rendimiento. Por ejemplo:- Con un uso elevado de la CPU, use la herramienta Uso de CPU para identificar las áreas en las que es posible que podamos optimizar el código. Para ver un tutorial sobre esto, consulte Caso práctico: Guía para principiantes para optimizar el código.
- Con un uso bajo de CPU, use la herramienta Instrumentación para identificar recuentos de llamadas y tiempo medio de función en función del tiempo del reloj. Esto puede ayudar a identificar problemas como la contención o la escasez del grupo de subprocesos.
-
Allocation Rate. Para una aplicación web que atiende solicitudes, la tarifa debe ser bastante estable. -
GC Heap Size. Vigile este contador para ver si el uso de memoria está aumentando continuamente y hay una posible fuga de memoria. Si parece alta, use una de las herramientas de uso de memoria. -
Threadpool Thread Count. Para una aplicación web que atiende solicitudes, vea este contador para ver si el recuento de subprocesos se mantiene estable o aumenta a una velocidad estable.
Este es un ejemplo que muestra cómo el CPU Usage es bajo, mientras que el ThreadPool Thread Count es relativamente alto.
Un número de subprocesos creciente constantemente con un uso bajo de CPU puede ser un indicador del colapso del grupo de subprocesos. El grupo de subprocesos se ve obligado a seguir hilando nuevos subprocesos. El colapso del grupo de subprocesos se produce cuando el grupo no tiene subprocesos disponibles para procesar nuevos elementos de trabajo y a menudo hace que las aplicaciones respondan lentamente.
Si existe un bajo uso de CPU y un recuento de subprocesos relativamente alto, y según la teoría de un posible caso de colapso del grupo de subprocesos, cambie al uso de la herramienta Instrumentación.
Investigar los recuentos de llamadas y los datos de tiempo
Echemos un vistazo a un seguimiento de la herramienta Instrumentación para ver si podemos intentar obtener más información sobre lo que sucede con los subprocesos.
Después de recopilar un seguimiento con la herramienta Instrumentación y cargarlo en Visual Studio, primero comprobamos la página inicial del informe .diagsession, donde se muestran los datos resumidos. En el seguimiento recopilado, usamos el vínculo Abrir detalles en el informe y, a continuación, seleccionamos Gráfico de llama.
La visualización de Flame Graph nos muestra que la función QueryCustomerDB (que se muestra en amarillo) es responsable de una parte significativa del tiempo de ejecución de la aplicación.
Haga clic con el botón derecho en la función QueryCustomerDB y elija Ver en árbol de llamadas.
La ruta de código con el mayor uso de CPU en la aplicación se denomina el camino caliente . El icono de llama de la ruta de acceso activa (
) puede ayudar a identificar rápidamente los problemas de rendimiento que podrían mejorarse.
En la vista Árbol de llamadas, puede ver que la ruta de acceso activa incluye la función QueryCustomerDB, lo que apunta a un posible problema de rendimiento.
En relación con el tiempo invertido en otras funciones, los valores de Self y Avg Self para la función QueryCustomerDB son muy altos. A diferencia de Total y Avg Total, los valores Self excluyen el tiempo invertido en otras funciones, por lo que este es un buen lugar para buscar el cuello de botella de rendimiento.
Sugerencia
Si los valores Propio eran relativamente bajos en lugar de altos, probablemente querrá examinar las consultas reales invocadas por la función QueryCustomerDB.
Haga doble clic en la función QueryCustomerDB para mostrar el código fuente de la función.
public ActionResult<string> QueryCustomerDB()
{
Customer c = QueryCustomerFromDbAsync("Dana").Result;
return "success:taskwait";
}
Hacemos una pequeña investigación. Como alternativa, podemos ahorrar tiempo y dejar que Copilot hacer la investigación para nosotros.
Si usamos Copilot, seleccione Pregunte a Copilot en el menú contextual y escriba la siguiente pregunta:
Can you identify a performance issue in the QueryCustomerDB method?
Sugerencia
Puede usar comandos de barra diagonal como /optimize para ayudar a formular preguntas apropiadas para Copilot.
Copilot nos indica que este código llama a una API asincrónica sin usar await. Este es el patrón de código sync-over-async, que es una causa común de colapso del grupo de subprocesos y puede bloquear los subprocesos.
Para resolverlo, use await. En este ejemplo, Copilot proporciona la siguiente sugerencia de código junto con la explicación.
public async Task<ActionResult<string>> QueryCustomerDB()
{
Customer c = await QueryCustomerFromDbAsync("Dana");
return "success:taskwait";
}
Si ve problemas de rendimiento relacionados con las consultas de base de datos, puede usar la herramienta Database para investigar si determinadas llamadas son más lentas. Estos datos pueden indicar una oportunidad para optimizar las consultas. Para ver un tutorial que muestra cómo usar la herramienta Base de datos para investigar un problema de rendimiento, consulte Caso práctico: Guía para principiantes para optimizar el código. La herramienta Database admite .NET Core con ADO.NET o Entity Framework Core.
Para obtener visualizaciones en Visual Studio de un comportamiento de subproceso individual, puede usar la ventana Pilas paralelas durante la depuración. En esta ventana se muestran subprocesos individuales junto con información sobre los subprocesos que están esperando, subprocesos en espera y bloqueos.
Para obtener información adicional sobre el colapso del grupo de subprocesos, consulte Detección del colapso del grupo de subprocesos.
Pasos siguientes
Los siguientes artículos y entradas de blog proporcionan más información para ayudarle a aprender a usar las herramientas de rendimiento de Visual Studio de forma eficaz.
- Caso práctico: Guía para principiantes sobre la optimización de código
- caso práctico: doble rendimiento en menos de 30 minutos
- mejorar el rendimiento de Visual Studio con la nueva herramienta de instrumentación