Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Cette étude de cas montre comment utiliser des outils de profilage Visual Studio pour identifier et résoudre les problèmes de performances dans un exemple d’application ASP.NET. Pour une comparaison des outils de profilage, consultez Quel outil dois-je choisir ?
Vous apprendrez ce qui suit :
- Comment utiliser les outils de profilage Visual Studio pour analyser les performances des applications.
- Comment interpréter les données de profilage pour trouver des goulots d’étranglement.
- Stratégies pratiques pour optimiser le code à l’aide de compteurs .NET, de nombres d’appels et de données de minutage.
Appliquez ces techniques pour améliorer vos propres applications.
Isoler une étude de cas sur un problème de performance
L'application ASP.NET d'exemple exécute des requêtes sur une base de données simulée et s'appuie sur l'exemple Diagnostics.
Symptômes de performance clés :
- Faible utilisation du processeur : le processeur n’est pas le goulot d’étranglement.
- Nombre élevé de threads ThreadPool : le nombre de threads augmente régulièrement, indiquant une saturation du pool de threads.
- Réponse lente de l’application : l’application répond lentement en raison d’un manque de threads disponibles.
Cette étude de cas utilise des outils de profilage Visual Studio pour identifier et résoudre ces problèmes, ce qui vous permet de rendre votre code plus rapide et plus efficace.
Défi
La résolution de ces problèmes implique plusieurs défis :
- Diagnostiquer des goulots d'étranglement : dans le cadre de lenteurs de fonctionnement, une faible utilisation du processeur peut avoir plusieurs causes. L’utilisation efficace des outils de profilage et l’interprétation de leur sortie est essentielle.
- Contraintes de connaissances et de ressources : le profilage et l’optimisation nécessitent des compétences et une expérience spécifiques, qui peuvent ne pas toujours être disponibles.
Une approche stratégique combinant des outils de profilage, des connaissances techniques et des tests prudents est essentielle pour surmonter ces défis.
Stratégie
Voici une vue générale de l’approche dans cette étude de cas :
- Commencez par surveiller les métriques de compteur .NET lors de la collecte des données de performance. L’outil .NET Counters de Visual Studio est un bon point de départ.
- Pour obtenir des insights plus approfondis, collectez des traces avec des outils de profilage supplémentaires, tels que l’outil Instrumentation pour le nombre d’appels et les données de minutage.
La collecte de données nécessite les tâches suivantes :
- Configurez l'application en version Release.
- Sélectionnez l’outil Compteurs .NET dans Performance Profiler (Alt+F2).
- Démarrez l’application et collectez une trace.
Vérifier les compteurs de performances
Lors de l’exécution de l’application, nous observons les compteurs dans l’outil Compteurs .NET. Pour les enquêtes initiales, gardez un œil sur quelques indicateurs clés, notamment :
-
CPU Usage. Regardez ce compteur pour déterminer si un problème de performances se produit avec une utilisation élevée ou faible du processeur. Il peut s’agir d’un indice sur des types spécifiques de problèmes de performances. Par exemple:- Avec une utilisation élevée du processeur, utilisez l’outil Utilisation du processeur pour identifier les zones où nous pouvons optimiser le code. Pour obtenir un didacticiel sur ce sujet, consultez Étude de cas : Guide du débutant pour optimiser le code.
- Avec une faible utilisation du processeur, utilisez l’outil Instrumentation pour identifier les nombres d’appels et le temps de fonction moyen en fonction de l’heure du mur. Cela peut aider à identifier des problèmes tels que la contention ou le threading pool starvation.
-
Allocation Rate. Pour une application web qui répond aux demandes, le taux doit être assez stable. -
GC Heap Size. Surveillez ce compteur pour voir si l'utilisation de la mémoire augmente continuellement et présente des fuites potentielles. S’il semble élevé, utilisez l’un des outils d’utilisation de la mémoire. -
Threadpool Thread Count. Pour une application web qui répond aux demandes, regardez ce compteur pour voir si le nombre de threads est stable ou augmente à un rythme stable.
Voici un exemple montrant comment la CPU Usage est faible, tandis que la ThreadPool Thread Count est relativement élevée.
Une augmentation constante du nombre de threads avec une faible utilisation du processeur peut être un indicateur de la faim du pool de threads. Le pool de threads est forcé de continuer à faire tourner de nouveaux threads. L'épuisement du pool de threads se produit lorsque le pool n’a pas de threads disponibles pour traiter de nouvelles tâches, ce qui entraîne souvent une réponse lente des applications.
En fonction de l’utilisation faible de l’UC et du nombre de threads relativement élevés, et en travaillant sur la théorie d’un cas possible de privation de pool de threads, basculez vers l’utilisation de l’outil Instrumentation.
Examiner les nombres d’appels et les données de minutage
Examinons une trace de l’outil Instrumentation pour voir si nous pouvons essayer d’en savoir plus sur ce qui se passe au niveau des threads.
Après avoir collecté une trace avec l’outil Instrumentation et en la chargeant dans Visual Studio, nous vérifions d’abord la page de rapport initiale .diagsession qui affiche les données résumées. Dans la trace collectée, nous utilisons le lien Ouvrir les détails dans le rapport, puis nous sélectionnons Flame Graph.
La visualisation de Flame Graph nous montre que la fonction QueryCustomerDB (illustrée en jaune) est responsable d’une partie importante du temps d’exécution de l’application.
Cliquez avec le bouton droit sur la fonction QueryCustomerDB et choisissez Affichage dans l’arborescence des appels.
Le chemin de code qui utilise le plus de processeur dans l'application est appelé chemin chaud. L’icône de flamme du chemin d'accès chaud (
) peut aider à identifier rapidement les problèmes de performances pouvant être améliorés.
Dans l'arborescence des appels, vous pouvez voir que le chemin chaud inclut la fonction QueryCustomerDB, ce qui indique un problème potentiel de performance.
Par rapport au temps passé dans d’autres fonctions, les valeurs Self et Avg Self pour la fonction QueryCustomerDB sont très élevées. Contrairement à Total et Moyenne Totale, les valeurs Self excluent le temps passé dans d’autres fonctions, ce qui en fait un bon endroit pour rechercher le goulot d’étranglement des performances.
Conseil
Si les valeurs de Self étaient relativement basses au lieu d’être élevées, vous aimeriez probablement examiner les requêtes réelles appelées par la fonction QueryCustomerDB.
Double-cliquez sur la fonction QueryCustomerDB pour afficher le code source de la fonction.
public ActionResult<string> QueryCustomerDB()
{
Customer c = QueryCustomerFromDbAsync("Dana").Result;
return "success:taskwait";
}
Nous faisons un peu de recherche. Nous pouvons également gagner du temps et laisser Copilot faire la recherche pour nous.
Si nous utilisons Copilot, sélectionnez Demander à Copilot dans le menu contextuel et tapez la question suivante :
Can you identify a performance issue in the QueryCustomerDB method?
Conseil
Vous pouvez utiliser des commandes obliques telles que /optimize pour vous aider à poser de bonnes questions à Copilot.
Copilot nous indique que ce code appelle une API asynchrone sans utiliser await. Il s’agit du modèle de code sync-over-async, est une cause de privation de pool de threads et êut bloquer les threads.
Pour résoudre ce problème, utilisez await. Dans cet exemple, Copilot fournit la suggestion de code suivante, ainsi que l’explication.
public async Task<ActionResult<string>> QueryCustomerDB()
{
Customer c = await QueryCustomerFromDbAsync("Dana");
return "success:taskwait";
}
Si vous constatez des problèmes de performances liés aux requêtes de base de données, vous pouvez utiliser l’outil de base de données pour déterminer si certains appels sont plus lents. Ces données peuvent indiquer une opportunité d’optimiser les requêtes. Pour obtenir un didacticiel montrant comment utiliser l’outil De base de données pour examiner un problème de performances, consultez Étude de cas : Guide du débutant pour optimiser le code. L’outil Base de données prend en charge .NET Core avec ADO.NET ou Entity Framework Core.
Pour obtenir des visualisations dans Visual Studio d’un comportement de thread individuel, vous pouvez utiliser la fenêtre Piles parallèles lors du débogage. Cette fenêtre affiche les threads individuels, ainsi que des informations sur les threads qui attendent, les threads qu’ils attendent et les blocages.
Pour plus d’informations sur la privation de pool de threads, consultez Détection de la privation de pool de threads.
Étapes suivantes
Les articles et billets de blog suivants fournissent plus d’informations pour vous aider à apprendre à utiliser efficacement les outils de performances de Visual Studio.
- Étude de cas : Guide d'optimisation du code pour les débutants
- Étude de cas : double performance en moins de 30 minutes
- Améliorer les performances de Visual Studio avec le nouvel outil d’instrumentation