Задание 8
.docТестирование производительности (профилирование)
Visual Studio Profiling Tool позволяет разработчикам измерять, оценивать производительность приложения и кода. Эти инструменты полностью встроены в IDE.
Методы профилирования
Sampling — собирает статистические данные о работе приложения (во время профилирования). Этот метод легковесный и поэтому, в результате его работы очень маленькая погрешность в полученных данных. Каждый определенный интервал времени собирается информация о стеке вызовов (call stack). На основе этих данные производится подсчет производительности. Используется для первоначального профилирования и для определения проблем связанных с использование процессора.
Instrumentation — собирает детализированную информацию о времени работы каждой вызванной функции. Используется для замера производительности операций ввода/вывода. Метод внедряет свой код в двоичный файл, который фиксирует информацию о синхронизации (времени) для каждой функции в файл, и для каждой функции которые вызываются в этой.
Отчет содержит 4 значения для предоставления затраченного времени:
-
Elapsed Inclusive — общее время, затраченное на выполнение функции
-
Application Inclusive — время, затраченное на выполнение функции, за исключением времени обращений к операционной системе.
-
Elapsed Exclusive — время, затраченное на выполнение кода в теле. Время, которое тратят функции, вызванные целевой функцией.
-
Application Exclusive — время, затраченное на выполнение кода в теле. Исключается время, которое тратится выполнения вызовов операционной системы и время, затраченное на выполнение функций, вызванные целевой функцией.
Concurrency – собирает информацию о многопоточных приложения. Метод собирает подробную информацию о стеке вызовов, каждый раз, когда конкурирующие потоки вынуждены ждать доступа к ресурсу.
.NET Memory — профайлер собирает информацию о типе, размере, а также количество объектов, которые были созданы в распределении или были уничтожены сборщиком мусора. Профилирование памяти почти не влияет на производительность приложения в целом.
Tier Interaction – добавляет информацию в файл для профилирования о синхронных вызовах ADO.NET между страницей ASP.NET или другими приложениями и SQL сервера. Данные включают число и время вызовов, а также максимальное и минимальное время.
Задание
-
Профилирование Выборкой (Sampling)
-
Откройте тестовый проект PeopleTrax в MS VS 2010 Premium и Ultimate. Установите конфигурацию в Release (в Debug будут не точные результаты).
-
В меню Анализ( Analyze) нажмите на Запустить мастер производительности (Launch Performance Wizard).
-
Выберите Выборка циклов ЦП (CPU Sampling (recommended))
-
Выбираем какое приложение мы будем профилировать, это PeopleTrax.
-
В следующем нажмите Finish и автоматически запустится профайлер и приложение. На экране - программа PeopleTrax. Нажмите кнопку Get People, ждите завершения работы и Export Data. Закройте блокнот и программу. Профайлер сгенерирует отчет.
-
Профайлер сгенерировал отчет (*.vsp)
В Сводке (Summary) отображается график использования процессора в течение всего времени профилирования. Список Горячего пути (Hot Path) показывает ветки вызовов, которые проявили наибольшую активность. А в списке Функции повлиявшие на ….(Functions Doing Most Individual Work)– функции, которые занимали большее время процесса в теле этих функций.
Например метод PeopleNS.People.GetNames занимает почти последнее место в ветке вызовов. Его производительность можно улучшить. Нажимаем на PeopleNS.People.GetNames и открывается Сведения о функции (Function Details)
Это окно содержит две части. Окно Распределение стоимости - графическое представление работы функций, и вклад функции и вызывающих ее на количество экземпляров, которые были отобраны. Можно изменить рассматриваемую функцию, нажав на нее мышкой.
Представление кода функции (Function Code View) показывает код метода, когда он доступен и подсвечивает наиболее «дорогие» строки в выбранном методе. Когда выбран метод GetNames видно, что он читает строки из ресурсов приложения используя StringReader, добавляя каждую строку в ArrayList. Нет очевидных способов улучшить эту часть.
Так как PeopleNS.People.GetPeople единственный, кто вызывает GetNames – нажимаем GetPeople. Этот метод возвращает ArrayList объектов PersonInformationNS.PersonInformation с именами людей и компаний, возвращенными методом GetNames. Тем не менее, GetNames вызывается дважды каждый раз, когда создается PersonInformation. (Это и показано желтым и красным выделением). Очевидно, что можно легко оптимизировать метод, создавая списки только один раз вначале метода.
-
Включите альтернативную версию GetPeople. Для этого определите OPTIMIZED_GETPEOPLE как Символ условной компиляции (Conditional compilation symbol) в окне свойств проекта People и PeopleTrax.
-
Исправьте ошибку в проекте. В оптимизированном конструкторе класса не правильно написано имя ресурсов: нужно PeopleNS.Resources вместе PeopleNS.Resource. Если это не изменить, будут ошибки.
-
Оптимизированный метод заменит старый при следующей сборке.
Перезапустите профилирование в текущей сессии нажав Запустить профилирование (Launch with Profiling) в окне Обозреватель производительности (Performance Explorer). Нажмите на Get People и Export Data. Закройте блокнот и программу. Профайлер сгенерирует новый отчет.
-
Чтобы сравнить два отчета – выберите оба и из контекстного меню Сравнить отчеты о производительности (Compare Performance Reports).
Колонка разностная показывает разницу в производительности версии Базовое значение с более поздней Значением сравнения. Выбираем Включающие выборки (Inclusive Samples %) и Применить (Apply). Как видно выигрыш в производительности заметен.
-
Для закрепления материала возьмите свой проект и проведите профилирование выборкой. Найдите код, который можно было бы оптимизировать. Сравните результаты по аналогии с описанными (это + по выполнению работы. Студенты с максимальным значением плюсов будут освобождены от сдачи теории по Тестированию ПО).
-
Профилирование Инструментированным (Instrumentation) методом
Этот метод полезен при профилировании операций ввода вывода, запись на диск и при обмене данными по сети. Этот метод предоставляет больше информации чем предыдущий, но он несет с собой больше накладных расходов.
Анализ будет сконцентрирован на экспорте данных, в котором список людей записывается в файл блокнота.
-
В Обозревателе производительности (Performance Explorer) выберите Инструментирование (Instrumentation) и нажмите Запустить профилирование ( Start Profiling).
-
Нажмите Get People. После загрузки людей ждите 10 секунд и нажимайте Export Data. Закрываете блокнот и программу. Профилировщик сгенерирует отчет.
-
Отфильтруем ненужные сейчас данные профилирования данные. Отмечаем с 40-й до конца и нажимаем Фильтровать выделение(Filter by selection). Уже другой результат:
-
Горячий путь (Hot Path) показывает, что метод Concat занимает много времени (он также первый в списке Функции…..(Functions With Most Individual Work). Нажимаем на Concat, чтобы посмотреть детально информацию о методе. Профилировщик покажет такую картинку:
Анализируем метод в окне кода.
Прямого вызова Concat нет. Вместе этого есть использование операнда +=, который компилятор заменяет на методы System.String.Concat.
Любые изменения в строках в .NET приводят к уничтожению старой версии строки и созданию измененной строки.
Для оптимизации можно использовать класс StringBuilder который и предназначен для такой работы.
В проекте уже есть оптимизированный метод с использованием StringBuilder.
-
В проекте PeopleTrax добавляем переменную компиляции OPTIMIZED_EXPORTDATA. Сохраняем и снова запускаем профайлер и сравниваем отчеты. Сразу видно что моптимизировали вызовы Concat .
Очень важно запускать профилирование еще раз, даже есть видимые улучшения. Просмотр новых данных после исправления проблемы может показать другие проблемы в производительности приложений.
-
Проведите анализ выделения памяти. (!!!!!!!)