• Привет, Гость!
  • Войти
  • Регистрация
  • Записи
  • Форумы
  • Люди
  • Файлы
  • Работа
  • Технологии
  • Все
  • Новости
  • События
  • Статьи
  • Блоги

Профилирование приложений в Visual Studio 2010

Профилирование приложений в Visual Studio 2010

Oxozle
06.07.2010 14:08
Сегодня мы будем замерять производительность нашего приложения с помощью Visual Studio Profiling Tool.

Visual Studio Profiling Tool позволяет разработчикам измерять, оценивать производительность приложения и кода. Эти инструменты полностью встроены в IDE, чтобы предоставить разработчику беспрерывный контроль.
В этом руководстве мы по шагам профилируем приложение PeopleTrax используя Sampling и Instrumentation методы профилирования, чтобы выявить проблемы в производительности приложения.

image

Много картинок.

Подготовка


Для работы с этим руководством вам потребуется:
  • Microsoft Visual Studio 2010
  • Средние знания языка C#
  • Копия тестового приложения PeopleTrax, скачать можно с MSDN Code Gallery


Методы профилирования


Чуть-чуть отступим от главной темы статьи и рассмотрим возможные методы профилирования. Эту главу можно пропустить, используемые методы профилирования будут кратко описаны перед использованием.

Sampling

Sampling — собирает статистические данные о работе приложения (во время профилирования). Этот метод легковесный и поэтому, в результате его работы очень маленькая погрешность в полученных данных.

Каждый определенный интервал времени собирается информация о стеке вызовов (call stack). На основе этих данные производится подсчет производительности. Используется для первоначального профилирования и для определения проблем связанных с использование процессора.

Instrumentation

Instrumentation — собирает детализированную информацию о времени работы каждой вызванной функции. Используется для замера производительности операций ввода/вывода.

Метод внедряет свой код в двоичный файл, который фиксирует информацию о синхронизации (времени) для каждой функции в файл, и для каждой функции которые вызываются в этой.

Отчет содержит 4 значения для предоставления затраченного времени:
  • Elapsed Inclusive — общее время, затраченное на выполнение функции
  • Application Inclusive — время, затраченное на выполнение функции, за исключением времени обращений к операционной системе.
  • Elapsed Exclusive — время, затраченное на выполнение кода в теле. Время, которое тратят функции, вызванные целевой функцией.
  • Application Exclusive — время, затраченное на выполнение кода в теле. Исключается время, которое тратится выполнения вызовов операционной системы и время, затраченное на выполнение функций, вызванные целевой функцией.


Concurrency

Concurrency – собирает информацию о многопоточных приложения (как отлаживать многопоточные приложения см. «Руководство по отладке многопоточных приложений в Visual Studio 2010»). Метод собирает подробную информацию о стеке вызовов, каждый раз, когда конкурирующие потоки вынуждены ждать доступа к ресурсу.

.NET Memory

.NET Memory — профайлер собирает информацию о типе, размере, а также количество объектов, которые были созданы в распределении или были уничтожены сборщиком мусора. Профилирование памяти почти не влияет на производительность приложения в целом.

Tier Interaction

Tier Interaction – добавляет информацию в файл для профилирования о синхронных вызовах ADO.NET между страницей ASP.NET или другими приложениями и SQL сервера. Данные включают число и время вызовов, а также максимальное и минимальное время.

На этом рассмотрение методов профилирование закончим и продолжим учиться профилировать приложения.

Профилирование Sampling методом


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

Профилирование

Открываем тестовый проект PeopleTrax. Устанавливаем конфигурацию в Release (в Debug версию встраивается дополнительная информация для отладки приложения, и она плохо скажется на точности результатов профилирования).

В меню Analyze нажимаем на Launch Performance Wizard.

image

На этом шаге нужно выбрать метод профилирования. Выбираем CPU Sampling (recommended) и нажимаем Next.

image

Выбираем какое приложение мы будем профилировать, это PeopleTrax и кнопка Next. В следующем нажимаем Finish и автоматически запустится профайлер и наше приложение. На экране мы видим программу PeopleTrax. Нажимаем кнопку Get People, ждем завершения работы и Export Data. Закрываем блокнот и программу и профайлер сгенерирует отчет.

image

Профайлер сгенерировал отчет (*.vsp)

image

Анализ отчета Sampling метода

В Summary отображается график использования процессора в течение всего времени профилирования. Список Hot Path показывает ветки вызовов, которые проявили наибольшую активность. А в списке Functions Doing Most Individual Work (название которого говорит само за себя) – функции, которые занимали большее время процесса в теле этих функций.

Посмотрев на список Hot Path видим что метод PeopleNS.People.GetNames занимает почти последнее место в ветке вызовов. Его то и можно изучить внимательнее на предмет улучшения производительности. Нажимаем на PeopleNS.People.GetNames и перед нами открывается Function Details.

image

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

Function Code View показывает код метода, когда он доступен и подсвечивает наиболее «дорогие» строки в выбранном методе. Когда выбран метод GetNames видно, что он читает строки из ресурсов приложения используя StringReader, добавляя каждую строку в ArrayList. Нет очевидных способов улучшить эту часть.

Так как PeopleNS.People.GetPeople единственный, кто вызывает GetNames – нажимаем GetPeople. Этот метод возвращает ArrayList объектов PersonInformationNS.PersonInformation с именами людей и компаний, возвращенными методом GetNames. Тем не менее, GetNames вызывается дважды каждый раз, когда создается PersonInformation. (Это и показано желтым и красным выделением). Очевидно, что можно легко оптимизировать метод, создавая списки только один раз вначале метода.

image

Альтернативная версия GetPeople также есть в коде и мы ее сейчас включим. Для этого нужно определить OPTIMIZED_GETPEOPLE как Conditional compilation symbol в окне свойств проекта People и PeopleTrax. И да, если захотите повторить мои опыты, то нужно исправить ошибку в проекте. В оптимизированном конструкторе класса не правильно написано имя ресурсов: нужно PeopleNS.Resources вместе PeopleNS.Resource. Если это не изменить, все валится со страшными ошибками.

image

Оптимизированный метод заменит старый при следующей сборке.

Перезапускаем профилирование в текущей сессии нажав Launch with Profiling в окне Performance Explorer. Нажимаем на Get People и Export Data. Закрываем блокнот и программу а профайлер сгенерирует новый отчет.

image

Чтобы сравнить два отчета – выбираем оба и ПКМ Compare Performance Reports. Колонка дельты показывает разницу в производительности версии Baseline с более поздней Comparison. Выбираем Inclusive Samples % и Apply.

Как видно выигрыш в производительности заметен невооруженным глазом

image

Профилирование методом Instrumentation


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

В этот раз мы сосредоточим наш анализ на экспорте данных, в котором список людей записывается в файл блокнота.

Профилирование

В Performance Explorer выбираем Instrumentation и нажмаем Start Profiling. Нажимаем Get People. После загрузки людей ждем 10 секунд и нажмаем Export Data. Закрываем блокнот и программу. Профилировщик сгенерирует отчет.

Анализ

Профилировщик покажет такую картинку:

image

Мы не получили ту информацию, которую хотели. Отфильтруем данные. Мы специально ждали 10 секунд, чтобы просто отфильтровать ненужные сейчас данные профилирования. Отмечаем с 13-й до конца и нажимаем Filter by selection. Уже другой результат:

image

Hot Path показывает, что метод Concat занимает много времени (он также первый в списке Functions With Most Individual Work). Нажимаем на Concat, чтобы посмотреть детально информацию о методе.

image

Видно, что PeopleTrax.Form1.ExportData – единственный метод, который вызывает Concat. Нажимаем PeopleTrax.Form1.ExportData в вызывающих методах (Function calling this function).

image

Анализируем метод в окне кода. Обратите внимание, что нет прямого вызова Concat. Вместе этого есть использование операнда +=, который компилятор заменяет на методы System.String.Concat. Как уже почти все знают, что любые изменения в строках в .NET приводят к уничтожению старой версии строки и созданию измененной строки. К счастью в .NET есть класс StringBuilder который и предназначен для такой работы.

В проекте уже есть оптимизированный метод с использованием StringBuilder. В проекте PeopleTrax добавляем переменную компиляции OPTIMIZED_EXPORTDATA. Сохраняем и снова запускаем профайлер и сравниваем отчеты. Сразу видно (да и логически понятно) что мы оптимизировали вызовы Concat (с 6000 до 0 раз).

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

Литература


  • Getting Started with Profiling Tools
  • Walkthrough: Profiling Applications
  • PeopleTrax Sample (проект)
  • Visual Studio Profiler Team Blog
  • Руководство по отладке многопоточных приложений в Visual Studio 2010

Спасибо за внимание. Быстрого как молния вам кода.
Oxozle
06.07.2010 14:08
Комментариев:1 RSS Просмотров:1293
Теги: vs2010, профилирование, отладка, Visual Studio Profiling Tool
Victor.dev
06.07.2010 19:59
Спасибо за статью!
Ссылка

KLUBS

Oxozle Программирование C#/.NET
  • Блог

Облако тегов

parallel stacks parallel tasks productivity power tools security silverlight visual studio profiling tool vs2010 многопоточность отладка профилирование расширения
Строишь сложные системы? Хостинг от Parking.Ru

Записи

Популярные
  • diverofdark > C#: Expression Tree + Extension Method + Lambda как замена Safe Navigation Operator
  • sashaeve > Интересные возможности C# и ASP.NET
  • trukhinyuri > О чтении технической литературы в pdf на английском
  • snoralip > Обработка структурированн­ого текста с помощью регулярных выражений
  • Dmitryk > Парадигма генерации и обработки исключений
  • snoralip > Применение хеш-функций, SHA1, GetHashCode, HashSet и Dictionary
  • mvcdev > Говорящий PowerShell скрипт
  • mbakirov > I am back.
  • SergeyT. > [Перевод] Джозеф Албахари. Работа с потоками в C#. Часть 3
  • ][tiger > Singleton in .NET 4.0 - вопрос снят?
Все популярные записи
Обсуждаемые
  • mbakirov > I am back.
  • trukhinyuri > О чтении технической литературы в pdf на английском
  • diverofdark > C#: Expression Tree + Extension Method + Lambda как замена Safe Navigation Operator
  • NetGuru > Определение имени текущего пользователя SharePoint
  • snoralip > Применение хеш-функций, SHA1, GetHashCode, HashSet и Dictionary
  • Dmitryk > Парадигма генерации и обработки исключений
  • NetGuru > Строка подключения к БД.
  • Soldata > Преобразование даты в строку типа "вчера; сегодня; завтра" с помощью метода расширения
  • NetGuru > Extension methods – «методы-расшири­тели»:
  • trukhinyuri > Группы в Windows Live Messenger
Все обсуждаемые записи

Блоги

Новые
  • Regfor> Роман Калита – Блог
  • NetGuru> Kurakin Vit's Blog
  • Andrey> Андрей Веселов
  • danverPD> podzyubanBlogs
  • Stanislav Gornakov> Stanislav Gornakov
  • k0stya> k0stya
  • ][tiger> Just do IT - просто дует
  • Oxozle> KLUBS
  • mvcdev> WebDev
  • VitaliyP> PanarinV
Обсуждаемые
  • mihailik> Олег Михайлик
  • ceo> Нотатник Вiктора Шатохiна [MSFT]
  • gaidar> Gaidar Magdanurov
  • MikhailChernomo­rdikov> Mikhail Chernomordikov [MSFT]
  • Alexander Lozhechkin [MSFT]> Alexander Lozhechkin
  • agladkik> Andrey Gladkikh: Microsoft Dynamics
  • sergun> Sergey Zwezdin
  • beerbong> Bong Blog
  • sos> Dmitry Soshnikov [MSFT]
  • not-a-kernel-gu­y> Зеркало: Not a kernel guy
О сайте   Свяжитесь с нами   Версия для печати
Работает на 1С-Битрикс: Управление сайтом ASP.NET  |  Хостинг на Parking.Ru