Бөлісу құралы:


Пример. Изоляция проблемы с производительностью (C#, Visual Basic, F#)

В этом примере показано, как использовать средства профилирования Visual Studio для выявления и устранения проблем с производительностью в примере приложения ASP.NET. Сравнение средств профилирования см. в разделе "Какой инструмент следует выбрать?"

Вы узнаете:

  • Как использовать средства профилирования Visual Studio для анализа производительности приложений.
  • Как интерпретировать данные профилирования для поиска узких мест.
  • Практические стратегии оптимизации кода с помощью счетчиков .NET, счетчиков вызовов и данных о времени.

Применяйте эти методы для улучшения собственных приложений.

Выделение кейса исследования проблемы с производительностью

Пример приложения ASP.NET выполняет запросы к имитированной базе данных и основан на примере диагностики.

Ключевые симптомы производительности:

  • Низкое использование ЦП: ЦП не является узким местом.
  • Высокое количество потоков в пуле потоков: количество потоков постоянно растет, указывая на исчерпание пула потоков.
  • Медленный ответ приложения: приложение реагирует медленно из-за отсутствия доступных потоков.

В этом примере используются средства профилирования Visual Studio для выявления и устранения этих проблем, что помогает ускорить и повысить эффективность кода.

Вызов

Устранение этих проблем включает в себя несколько проблем:

  • Диагностика узких мест: низкое использование ЦП с низкой производительностью может иметь несколько причин. Эффективное использование средств профилирования и интерпретация их выходных данных имеет важное значение.
  • Ограничения знаний и ресурсов: профилирование и оптимизация требуют определенных навыков и опыта, которые могут быть недоступны не всегда.

Стратегический подход к сочетанию средств профилирования, технических знаний и тщательного тестирования является ключом к преодолению этих проблем.

Стратегия

Ниже приведено высокоуровневое представление подхода в этом примере:

  • Начните с мониторинга метрик счетчиков .NET при сборе данных о производительности. Средство счетчиков .NET в Visual Studio является хорошей отправной точкой.
  • Для более глубокой аналитики собирайте трассировки с помощью дополнительных средств профилирования, таких как Instrumentation tool для подсчета вызовов и данных о времени.

Для сбора данных требуются следующие задачи:

  • Установите для приложения релизную сборку.
  • Выберите средство счетчиков .NET в профилировщике производительности (ALT+F2).
  • Запустите приложение и соберите трассировку.

Проверка счетчиков производительности

Во время работы приложения мы наблюдаем счетчики в инструменте .NET Counters. Для первоначальных исследований некоторые ключевые метрики, за которыми следует следить, включают:

  • CPU Usage. Просмотрите этот счетчик, чтобы узнать, возникает ли проблема с производительностью с высоким или низким потреблением ЦП. Это может быть ключом к конкретным типам проблем с производительностью. Например:
    • При высокой загрузке ЦП используйте средство использования ЦП для выявления областей, где можно оптимизировать код. В качестве учебного пособия по этой теме см. Пример: Руководство для начинающих по оптимизации кода.
    • При низком использовании ЦП используйте инструмент инструментирования, чтобы определить количество вызовов и среднее время выполнения функции на основе времени по системным часам. Это может помочь выявить такие проблемы, как сопротивление или голодание пула потоков.
  • Allocation Rate. Для запросов на обслуживание веб-приложений скорость должна быть достаточно стабильной.
  • GC Heap Size. Просмотрите этот счетчик, чтобы следить за тем, растет ли использование памяти постоянно и может ли произойти утечка. Если кажется высоким, используйте один из средств использования памяти.
  • Threadpool Thread Count. Для запросов на обслуживание веб-приложений просмотрите этот счетчик, чтобы узнать, держится ли число потоков устойчивым или растет на стабильном уровне.

Ниже приведен пример, показывающий, как CPU Usage низкий, в то время как ThreadPool Thread Count относительно высок.

снимок экрана счетчиков, отображаемых в средстве счетчиков .NET.

Постоянно растущее число потоков с низким потреблением ЦП может быть индикатором нехватки пула потоков. Пул потоков вынужден продолжать создавать новые потоки. Истощение пула потоков происходит, когда пул не имеет доступных потоков для обработки новых рабочих заданий и часто вызывает медленную реакцию приложений.

На основе низкой загрузки ЦП и относительно высокого количества потоков и работы с теорией возможного случая нехватки пула потоков переключитесь на использование средства инструментирования.

Изучение количества вызовов и данных о времени

Давайте посмотрим на трассировку из инструмента мониторинга, чтобы попытаться понять, что происходит с потоками.

После сбора трассировки с помощью средства инструментирования и загрузки его в Visual Studio сначала проверьте первоначальную .diagsession страницу отчета, где представлены суммированные данные. В собранной трассировке мы используем ссылку Открыть сведения в отчете, а затем выбираем график пламени.

снимок экрана:

Визуализация "Диаграмма пламени" показывает, что функция QueryCustomerDB (показанная желтым цветом) отвечает за значительную часть времени выполнения приложения.

Щелкните правой кнопкой мыши функцию QueryCustomerDB и выберите просмотр в дереве вызовов.

Снимок экрана Дерева Вызовов в Инструментальном Средстве.

Путь кода с наибольшим использованием ЦП в приложении называется горячим путем. Значок горячего пути (снимок экрана со значком ) может помочь быстро определить проблемы с производительностью для улучшения.

В представлении дерева вызовов видно, что горячий путь включает функцию QueryCustomerDB, которая указывает на потенциальную проблему производительности.

По сравнению с временем, затраченным на другие функции, значения Self и Avg Self для функции QueryCustomerDB очень высоки. В отличие от Total и Avg Total, значения Self исключают время, затраченное на другие функции, поэтому это хорошее место для поиска узких мест производительности.

Совет

Если значения self были относительно низкими, а не высокими, вероятно, потребуется просмотреть фактические запросы, вызываемые функцией QueryCustomerDB.

Дважды щелкните функцию QueryCustomerDB, чтобы отобразить исходный код функции.

public ActionResult<string> QueryCustomerDB()
{
    Customer c = QueryCustomerFromDbAsync("Dana").Result;
    return "success:taskwait";
}

Мы делаем небольшое исследование. Кроме того, мы можем сэкономить время и позволить Copilot сделать исследования для нас.

Если мы используем Copilot, выберите Ask Copilot в контекстном меню и введите следующий вопрос:

Can you identify a performance issue in the QueryCustomerDB method?

Совет

Для формирования хороших вопросов для Copilot можно использовать слэш-команды, такие как /optimize.

Copilot сообщает нам, что этот код вызывает async API без использования await. Это шаблон кода синхронизации поверх асинхронного, что является распространенной причиной истощения пула потоков и может приводить к блокировке потоков.

Для разрешения используйте await. В этом примере Copilot предоставляет следующее предложение кода вместе с объяснением.

public async Task<ActionResult<string>> QueryCustomerDB()
{
    Customer c = await QueryCustomerFromDbAsync("Dana");
    return "success:taskwait";
}

Если возникают проблемы с производительностью, связанные с запросами к базе данных, можно использовать средство базы данных для изучения того, являются ли некоторые вызовы медленнее. Эти данные могут указывать на возможность оптимизации запросов. Для получения сведений о том, как использовать средство базы данных для анализа проблемы с производительностью, см. Пример из практики: руководство для начинающих по оптимизации кода. Инструмент работы с базой данных поддерживает .NET Core с ADO.NET или Entity Framework Core.

Чтобы получить визуализации в Visual Studio для поведения отдельных потоков, можно использовать окно Параллельные стеки во время отладки. В этом окне отображаются отдельные потоки, а также информация о потоках, которые находятся в ожидании, потоках, на которые они ожидают, и взаимоблокировках.

Дополнительные сведения о нехватке пула потоков см. в разделе Обнаружение истощения пула потоков.

Дальнейшие действия

В следующих статьях и блогах содержатся дополнительные сведения, которые помогут вам эффективно использовать средства производительности Visual Studio.