Устранение проблем производительности приложений

 

 

За 20 лет мы стали свидетелями постоянного увеличения мощности процессоров, которые отчасти могли нивелировать вопросы оптимизации производительности. Можно было надеяться, что выпускаемое программное обеспечение будет работать на следующем поколении более быстрых процессоров. Так оно часто и случалось, и даже некоторые потребители были готовы менять оборудование раз в 3-4 года. Но текущая ситуация осложнилась тем что на рынке возникли новые форм-факторы и устройства - такие как компактные компьютеры, нетбуки, планшеты, и смартфоны. В этих устройствах производительность часто жертвуется в угоду времени работы от батарейки, ограничен объем оперативной памяти.

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

Режимы оценки производительности

Профайлер Visual Studio 2010 поддерживает несколько режимов оценки производительности анализируемой программы:

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

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

· Concurrency: Сбор подробных сведений в многопоточном приложении. Анализ производительности таких приложений является сложной задачей и в Visual Studio предусмотрены инструменты облегчающие идентификацию потоков, а так же позволяющие выявить конфликты в захватах общих ресурсов, измерить время ожидания потоков. С помощью специальных визуализаторов возможен анализ избыточного использования ЦП, конфликты потоков, миграцию потоков, задержки синхронизации, области перекрывающихся операций ввода-вывода и другие сведения

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

· Tier Interaction: Сбор подробных сведений в многоуровневых приложениях, например при взаимодействии ASP.NET слоя с базой данных SQL Server.

Работа с профайлером

Для того чтобы начать анализ производительности вашего приложения достаточно вызвать мастер « Performance Wizard» через меню Analyze. Только не забудьте запустить Visual Studio от лица администратора, это требуется для вызова специальных функций операционной системы, не доступных в обычном пользовательском режиме.

image001

После окончания работы вашего приложения откроется окно с первичными данными хода выполнения программы из которого уже можно будет извлечь ценные сведения о частоте и времени выполнения тех или иных функций:

image002

В этом отчете есть таблица с двумя важными параметрами:

  • Inclusive Samples: Данный параметр показывает показывает сколько работы было проделано функцией или функциями вызванными ею по отношению к всему выполненному коду в программе. Высокие значения этого параметра показывают насколько "дорого" обходится вызов этой функции.
  • Exclusive samples: Данный параметр показывает сколько было выполнено кода в теле функции, исключая тот код который был вызван. Высокие значения этого параметра показывают на проблемы производительности в этой конкретной функции

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

image003

Судя по реализованному алгоритму, функция GetNames вызываемая из функции GetPeople постоянно создает массив names, который на самом деле мы можем подготавливать заранее. Пример который используется уже содержит оптимизированный вариант этой функции, и для того чтобы переключится, достаточно добавить в Conditional Compilation условие OPTIMIZED_GETPEOPLE

image004

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

image005

image006

Рекомендации по устранению проблем производительности

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

Если во время анализа программы были выявлены такие случаи, то в окне отчета в разделе Notifications появится пункт View Guidance:

image007

Нажав на который можно будет увидеть рекомендации по исправлению участка кода:

image008

Перечень этих рекомендаций настраивается в свойствах среды Visual Studio 2010:

image009

Детальную информацию об этих правилах и рекомендации по устранению проблем производительности можно узнать в разделе MSDN Справочник по правилам производительности в средствах профилирования

Конечно, возможности профайлера не ограничиваются этим простым примером. Более подробно об этом инструменте можно узнать на сайте MSDN (на русском языке):