Analiza przypadku: Izolowanie problemu z wydajnością (C#, Visual Basic, F#)
Użyj narzędzi profilowania, aby zbadać problemy z wydajnością i odizolować obszary problemów. W tym badaniu przypadku użyto przykładowej aplikacji z problemami z wydajnością, aby zademonstrować sposób używania narzędzi profilowania w celu zwiększenia wydajności. Jeśli chcesz porównać narzędzia profilowania, zobacz Które narzędzie należy wybrać?
W tym badaniu przypadku omówiono następujące tematy:
- Jak używać narzędzi profilowania programu Visual Studio do analizowania wydajności aplikacji.
- Sposób interpretowania danych dostarczonych przez te narzędzia w celu zidentyfikowania wąskich gardeł wydajności.
- Jak zastosować praktyczne strategie optymalizacji kodu, koncentrując się na licznikach platformy .NET, licznikach wywołań i danych o chronometrażu.
Postępuj zgodnie z instrukcjami, a następnie zastosuj te techniki do własnych aplikacji, aby uczynić je bardziej wydajnymi i ekonomicznymi.
Wydziel przypadek opisujący problem z wydajnością
Przykładowa aplikacja w tym badaniu przypadku jest aplikacją ASP.NET, która uruchamia zapytania względem symulowanej bazy danych. Przykład jest oparty na przykładzie Diagnostics Sample.
Podstawowym problemem z wydajnością przykładowej aplikacji jest nieefektywne wzorce kodowania. Aplikacja ma wąskie gardło wydajności, które znacząco wpływa na wydajność. Problem obejmuje następujące objawy:
Niskie użycie CPU: Aplikacja wykazuje niskie użycie CPU, co wskazuje, że procesor nie jest wąskim gardłem.
Wysoka liczba wątków w puli wątków: liczba wątków jest stosunkowo wysoka i stale rośnie, co sugeruje wyczerpanie zasobów puli wątków.
Powolna reakcja aplikacji: Aplikacja reaguje powoli z powodu niedostępności wątków do przetwarzania nowych elementów roboczych.
Analiza przypadku ma na celu rozwiązanie tych problemów dzięki zastosowaniu narzędzi profilowania programu Visual Studio w celu przeanalizowania wydajności aplikacji. Dzięki zrozumieniu, gdzie i jak można poprawić wydajność aplikacji, deweloperzy mogą implementować optymalizacje, aby kod był szybszy i bardziej wydajny. Ostatecznym celem jest zwiększenie ogólnej wydajności aplikacji, co czyni ją bardziej wydajną i opłacalną do uruchomienia.
Wyzwanie
Rozwiązywanie problemów z wydajnością w przykładowej aplikacji .NET stanowi kilka wyzwań. Te wyzwania wynikają ze złożoności diagnozowania wąskich gardeł wydajności. Kluczowe wyzwania związane z rozwiązywaniem opisanych problemów są następujące:
Diagnozowanie wąskich gardeł wydajności: Jednym z głównych wyzwań jest precyzyjne określenie głównych przyczyn problemów z wydajnością. Niskie użycie CPU w połączeniu ze spowolnioną wydajnością może mieć wiele czynników przyczyniających się. Deweloperzy muszą skutecznie używać narzędzi profilowania do diagnozowania tych problemów, co wymaga zrozumienia sposobu działania tych narzędzi i interpretowania danych wyjściowych.
Ograniczenia wiedzy i zasobów: Zespoły mogą napotkać ograniczenia związane z wiedzą, doświadczeniem i zasobami. Profilowanie i optymalizowanie aplikacji wymaga określonych umiejętności i doświadczenia, a nie wszystkich zespołów może mieć natychmiastowy dostęp do tych zasobów.
Rozwiązanie tych wyzwań wymaga strategicznego podejścia, które łączy skuteczne wykorzystanie narzędzi profilowania, wiedzy technicznej i starannego planowania i testowania. Analiza przypadku ma na celu poprowadzenie deweloperów przez ten proces, zapewnienie strategii i szczegółowych informacji w celu przezwyciężenia tych wyzwań i poprawy wydajności aplikacji.
Strategia
Oto ogólny widok podejścia w tym badaniu przypadku:
- Rozpoczynamy badanie, monitorując metryki liczników platformy .NET podczas zbierania danych o wydajności. Podobnie jak narzędzie użycia procesora CPU, narzędzie .NET Counters programu Visual Studio jest również dobrym punktem wyjścia do badania wydajności.
- Następnie, aby uzyskać dodatkowe szczegółowe informacje, aby pomóc w odizolowaniu problemów lub poprawić wydajność, rozważ zebranie śladu przy użyciu jednego z innych narzędzi profilowania. Na przykład, zapoznaj się z liczbą wywołań i danymi czasowymi przy użyciu narzędzia instrumentacji.
Zbieranie danych wymaga następujących zadań:
- Ustawianie aplikacji na wersję produkcyjną.
- Wybierz narzędzie Liczniki .NET z narzędzia Profilowania Wydajności (Alt+F2). (Późniejsze kroki obejmują narzędzie instrumentacji).
- Z poziomu profilera wydajności uruchom aplikację i zbierz ślad.
Sprawdzanie liczników wydajności
Podczas uruchamiania aplikacji obserwujemy liczniki w narzędziu Liczniki platformy .NET. W przypadku wstępnych badań warto zwrócić uwagę na kilka kluczowych metryk, takich jak:
-
CPU Usage
. Obejrzyj ten licznik, aby sprawdzić, czy wysoki lub niski poziom wykorzystania procesora powoduje problem z wydajnością. Może to być wskazówka dla konkretnych typów problemów z wydajnością. Na przykład:- Przy wysokim użyciu CPU, użyj narzędzia Użycie procesora, aby zidentyfikować obszary, w których możemy zoptymalizować kod. Aby zapoznać się z tym samouczkiem, zobacz Analiza przypadku: Przewodnik dla początkujących dotyczący optymalizowania kodu.
- Przy niskim użyciu procesora CPU użyj narzędzia Instrumentacja, aby zidentyfikować liczby wywołań i średni czas funkcji na podstawie czasu zegara ściany. Może to pomóc w zidentyfikowaniu problemów, takich jak zawężenie lub wyczerpanie puli wątków.
-
Allocation Rate
. Dla aplikacji internetowej obsługującej żądania tempo powinno być dość stabilne. -
GC Heap Size
. Obejrzyj ten licznik, aby sprawdzić, czy użycie pamięci stale rośnie i potencjalnie przecieka. Jeśli wydaje się to wysokie, użyj jednego z narzędzi do użycia pamięci. -
Threadpool Thread Count
. Aby obsłużyć żądania w aplikacji internetowej, obserwuj ten licznik, aby sprawdzić, czy liczba wątków utrzymuje się na stałym poziomie lub rośnie w stałym tempie.
Oto przykład pokazujący, jak CPU Usage
jest niska, a ThreadPool Thread Count
jest stosunkowo wysoka.
Ciągle rosnąca liczba wątków przy niskim użyciu procesora może być wskaźnikiem głodu puli wątków. Wątkowa pula jest zmuszona do tworzenia nowych wątków. Głodowanie puli wątków występuje, gdy pula nie ma dostępnych wątków do przetwarzania nowych elementów roboczych i często powoduje powolne reagowanie aplikacji.
Na podstawie niskiego użycia procesora i stosunkowo dużej liczby wątków oraz pracy nad teorią możliwego przypadku zablokowania puli wątków, przejdź na używanie narzędzia Instrumentacja.
Badanie liczby wywołań i danych dotyczących czasu
Przyjrzyjmy się śladowi z narzędzia Instrumentacja, aby dowiedzieć się więcej o tym, co dzieje się z wątkami.
Po zebraniu śladu za pomocą narzędzia Instrumentacja i załadowaniu go do programu Visual Studio, przede wszystkim sprawdzamy początkową stronę raportu .diagsession, która zawiera podsumowane dane. W zebranym śladzie korzystamy z linku Otwórz szczegóły w raporcie, a następnie wybieramy Flame Graph.
Wizualizacja Flame Graph pokazuje, że funkcja QueryCustomerDB
(pokazana na żółto) jest odpowiedzialna za znaczną część czasu działania aplikacji.
Kliknij prawym przyciskiem myszy funkcję QueryCustomerDB
i wybierz pozycję widok w drzewie wywołań.
Ścieżka kodu o najwyższym użyciu procesora CPU w aplikacji jest nazywana ścieżką gorącą . Ikona płomienia ścieżki gorącej () może pomóc w szybkim zidentyfikowaniu problemów z wydajnością, które mogą zostać ulepszone.
W widoku drzewa wywołań widać, że ścieżka gorąca zawiera funkcję QueryCustomerDB
, która wskazuje na potencjalny problem z wydajnością.
W stosunku do czasu spędzonego w innych funkcjach wartości Self i Avg Self dla funkcji QueryCustomerDB
są bardzo wysokie. W przeciwieństwie do wartości Total i Avg Total, wartości Self wykluczają czas spędzony w innych funkcjach, dlatego jest to dobre miejsce, aby wyszukać wąskie gardło wydajności.
Napiwek
Jeśli wartości Self były stosunkowo niskie, a nie wysokie, prawdopodobnie warto przyjrzeć się rzeczywistym zapytaniom wywoływanym przez funkcję QueryCustomerDB
.
Kliknij dwukrotnie funkcję QueryCustomerDB
, aby wyświetlić kod źródłowy funkcji.
public ActionResult<string> QueryCustomerDB()
{
Customer c = QueryCustomerFromDbAsync("Dana").Result;
return "success:taskwait";
}
Robimy trochę badań. Alternatywnie możemy zaoszczędzić czas i pozwolić Copilot zrobić badania dla nas.
Jeśli używamy Copilot , wybierz pozycję Ask Copilot z menu kontekstowego i wpisz następujące pytanie:
Can you identify a performance issue in the QueryCustomerDB method?
Napiwek
Możesz użyć poleceń ze znakiem ukośnika, takich jak /optimize, aby pomóc w tworzeniu dobrych pytań dotyczących Copilot.
Copilot informuje nas, że ten kod wywołuje asynchroniczny interfejs API bez użycia funkcji await. Jest to wzorzec kodu sync-over-async, który jest częstą przyczyną wyczerpania zasobów puli wątków i może prowadzić do blokowania wątków.
Aby rozwiązać ten problem, użyj funkcji await. W tym przykładzie copilot udostępnia następującą sugestię kodu wraz z wyjaśnieniem.
public async Task<ActionResult<string>> QueryCustomerDB()
{
Customer c = await QueryCustomerFromDbAsync("Dana");
return "success:taskwait";
}
Jeśli widzisz problemy z wydajnością związane z zapytaniami bazy danych, możesz użyć narzędzia Database w celu zbadania, czy niektóre wywołania są wolniejsze. Te dane mogą wskazywać na możliwość optymalizacji zapytań. Aby zapoznać się z samouczkiem pokazującym, jak za pomocą narzędzia Baza danych zbadać problem z wydajnością, zobacz Analiza przypadku: Przewodnik dla początkujących dotyczący optymalizowania kodu. Narzędzie do baz danych obsługuje platformę .NET Core z ADO.NET lub Entity Framework Core.
Aby uzyskać wizualizacje w programie Visual Studio dla zachowania poszczególnych wątków, możesz użyć okna Parallel Stacks podczas debugowania. W tym oknie są wyświetlane poszczególne wątki wraz z informacjami o wątkach, które oczekują, wątkach, na które czekają, oraz zakleszczenia.
Aby uzyskać dodatkowe informacje na temat głodu puli wątków, zobacz Wykrywanie głodu puli wątków.
Następne kroki
Poniższe artykuły i wpisy w blogu zawierają więcej informacji, aby ułatwić efektywne korzystanie z narzędzi do wydajności programu Visual Studio.
- Analiza przypadku: Przewodnik dla początkujących dotyczący optymalizowania kodu
- Analiza przypadku: podwójna wydajność w czasie poniżej 30 minut
- poprawianie wydajności programu Visual Studio przy użyciu nowego narzędzia Instrumentation Tool