Характеристики производительности приложений .NET Framework

76

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

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

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

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

Требования к производительности

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

Для начала перечислим несколько примеров неправильно сформулированных требований:

Основная проблема этих требований в том, что они являются слишком общими и субъективными. Если попытаться вникнуть в их суть, можно обнаружить, что в разных системах отсчета они могут интерпретироваться по-разному. Бизнес-аналитик может считать, что 100 000 одновременно работающих пользователей - это «немного», а технический специалист может с уверенностью сказать, что такое количество пользователей невозможно обслужить, имея единственную машину. Аналогично, разработчик может считать пользовательский интерфейс с задержками 500 мсек вполне «отзывчивым», а эксперт в пользовательских интерфейсах оценивать это как серьезный недостаток.

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

В этих примерах предполагается, что категория страниц «Важные» и категория запросов «Общие» четко определены бизнес-аналитиками и архитекторами приложения. Определение требований к производительности для каждого аспекта приложения часто неразумно и не стоит затраченных усилий.

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

Примеры требований к производительности для типичных приложений
Тип системы Требование к производительности Ограничения окружения
Внешний веб-сервер Время от момента получения запроса до момента создания полного ответа не должно превышать 300 мсек При условии одновременной обработки не более 300 запросов
Внешний веб-сервер Объем используемой виртуальной памяти (включая кеш) не должен превышать 1.3 Гбайт При условии одновременной обработки не более 300 запросов и не более 5000 открытых сеансов пользователей
Сервер приложений Нагрузка на CPU не должна превышать 75% При условии не более 1000 одновременно обслуживаемых запросов к API
Сервер приложений Частота следования ошибок обращений к страницам диска не должна превышать 2 ошибок в сек При условии не более 1000 одновременно обслуживаемых запросов к API
Клиентское приложение Время от двойного щелчка на ярлыке до появления полного списка клиентов не должно превышать 1500 мсек -
Клиентское приложение Нагрузка на CPU в режиме простоя приложения не должна превышать 1% -
Веб-страница Время фильтрации и сортировки списка входящих электронных писем не должно превышать 750 мсек, включая время, затрачиваемое на воспроизведение анимационных эффектов При отображении не более 200 электронных писем
Веб-страница Объем памяти для хеширования объектов JavaScript в окне не должен превышать 2.5 Мбайт -
Служба мониторинга Время от возникновения ошибки до вывода предупреждения не должно превышать 25 мсек -
Служба мониторинга Частота следования операций дискового ввода/вывода в отсутствие активных предупреждений должна быть равна 0 -

Параметры аппаратного обеспечения, на котором выполняется приложение, играют ключевую роль в определении ограничений среды. Например, требование к скорости запуска клиентского приложения может потребовать использования твердотельного накопителя или жесткого диска со скоростью вращения шпинделя не менее 7200 об/мин, по меньшей мере 2 Гбайт системной памяти и процессора с тактовой частотой 1.2 Ггц или выше, поддерживающего набор инструкций SSE3. Эти требования к аппаратному обеспечению не стоит повторять в описании каждого требования к производительности, но о них следует помнить.

Когда требования к производительности сформулированы, тестирование производительности, нагрузочное тестирование и последующий процесс оптимизации становятся тривиальным делом. Проверка таких требовании, как «частота следования ошибок обращений к страницам диска не должна превышать 2 ошибок в сек, при условии не более 1000 одновременно обслуживаемых запросов к API» часто может потребовать применения инструментов нагрузочного тестирования и подходящего аппаратного обеспечения. В последующих статьях рассматриваются приемы измерения производительности приложений позволяющие определить степень соответствия предъявляемым требованиям.

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

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

В отличие от требований к производительности, характеристики производительности не связаны с каким-то конкретным типом приложения или окружением. Характеристики производительности - это числовое выражение особенностей поведения приложения. Они могут измеряться на любом аппаратном обеспечении и в любом окружении, независимо от количества активных пользователей, запросов или сеансов. В процессе разработки вы выбираете характеристики для измерения и на их основе определяете требования к производительности.

Некоторые приложения имеют характеристики, специфичные для своей области. Мы не будем пытаться идентифицировать их здесь Вместо этого перечислим в таблице характеристики, наиболее важные для большинства приложений. (Нагрузка на CPU и время выполнения являются настолько важными характеристиками, что упоминаются в каждой статье, связанной с оптимизацией.)

Список характеристик производительности (частичный)
Характеристика Единицы измерения
Нагрузка на CPU Процент
Использование физической/виртуальной памяти Байты, килобайты, мегабайты, гигабайты
Попадания в кеш Количество,частота попаданий в секунду
Ошибки обращений к страницам диска Количество, частота следования в секунду
Обращения к базе данных Количество обращений, частота следования в секунду
Выделение блоков памяти Количество байтов, количество объектов, частота следования в секунду
Время выполнения Миллисекунды
Сетевые операции Количество, частота следования в секунду
Дисковые операции Количество, частота следования в секунду
Время отклика Миллисекунды
Сборка мусора Количество, частота следования в секунду, продолжительность, % от общего времени выполнения
Исключительные ситуации Количество, частота следования в секунду
Время запуска Миллисекунды
Конкуренция Количество, частота следования в секунду

Одни характеристики более важны для одних типов приложений, другие - для других. Например, время доступа к базе данных не является характеристикой, которую можно измерить на стороне клиента. В число наиболее типичных комбинаций характеристик производительности входят:

И последнее наблюдение, касающееся характеристик производительности, - уровень детализации измерений часто может изменяться существенно, что, впрочем, никак не влияет на важность самих характеристик. Например, время выделения памяти или время выполнения могут измеряться на уровне системы, на уровне единственного приложения или даже на уровне отдельных методов или строк. Время выполнения одного конкретного метода может оказаться гораздо важнее, чем общая нагрузка на CPU или время выполнения процесса в целом! К сожалению, увеличение уровня детализации измерений часто влечет за собой дополнительные накладные расходы.

Место производительности в цикле разработки

Куда в цикл разработки следует вставить решение вопросов, связанных с производительностью? Этот, казалось бы невинный вопрос, влечет за собой необходимость модернизации всего процесса разработки. Для этих целей можно было бы выделить отдельный этап. Однако правильнее уделять внимание проблемам производительности на каждом этапе разработки приложения: сначала следует выявить наиболее важные характеристики и определить требования к производительности; затем выяснить, насколько полно приложение отвечает этим требованиям; и, наконец, на этапе дальнейшего развития и эксплуатации следить, как изменяются показатели производительности.

  1. На этапе определения требований к приложению начинайте одновременно выяснять параметры производительности, которые было бы желательно получить.

  2. На этапе проектирования очертите круг наиболее важных характеристик производительности для вашего приложения и определите конкретные их значения.

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

  4. На этапе тестирования выполняйте всеобъемлющие нагрузочные испытания и тестирование производительности, чтобы убедиться, что производительность системы в целом соответствует установленным требованиям.

  5. В дальнейшем, во время разработки и сопровождения, выполняйте дополнительные нагрузочные испытания и тестирование производительности перед выпуском каждой новой версии (желательно ежедневно или хотя бы раз в неделю), чтобы быстро выявить снижение производительности, вызванное добавлением новых или изменением существующих функций.

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

Пройди тесты
Лучший чат для C# программистов