Поделиться через


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

Используйте средства профилирования для изучения проблем с производительностью и изоляции проблемных областей. В этом примере используется пример приложения с проблемами производительности, чтобы продемонстрировать, как использовать средства профилирования для повышения эффективности. Если вы хотите сравнить средства профилирования, см. Какой инструмент следует выбрать?

В этом примере рассматриваются следующие темы:

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

Следуйте инструкциям, а затем применяйте эти методы к собственным приложениям, чтобы сделать их более эффективными и экономичными.

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

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

Основная проблема с производительностью примера приложения заключается в неэффективных шаблонах кодирования. Приложение имеет узкие места производительности, что значительно влияет на ее эффективность. Проблема включает следующие симптомы:

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

  • Высокое количество потоков в ThreadPool: количество потоков относительно высокое и неуклонно растет, что указывает на нехватку в пуле потоков.

  • медленный ответ приложения. Приложение реагирует медленно из-за отсутствия доступных потоков для обработки новых рабочих элементов.

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

Вызов

Устранение проблем с производительностью в примере приложения .NET представляет несколько проблем. Эти проблемы связаны с сложностью диагностики узких мест производительности. Основные проблемы, связанные с устранением проблем, описанных ниже.

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

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

Для решения этих проблем требуется стратегический подход, который объединяет эффективное использование средств профилирования, технических знаний и тщательного планирования и тестирования. Кейс-стадия ставит своей целью руководить разработчиками в этом процессе, предоставляя стратегии и инсайты для преодоления этих проблем и повышения производительности приложения.

Стратегия

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

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

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

  • Настройка приложения на релизную сборку.
  • Выберите средство счетчиков .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.