Производительность – одна из важнейших характеристика любого приложения, на ряду с функциональностью и дизайном. Она же является одной из распространенных причин неудачного завершения процесса сертификации и публикации приложения в Windows Store.
Хорошее приложение должно быть быстрыми, работать плавно и экономно расходовать аппаратные ресурсы. Для этого, производительности необходимо уделять внимание, так же, как дизайну и функциональным возможностям.
В Visual Studio 2013 появились новые возможности профилирования и анализа производительности, которые позволяют быстро находить распространенные узкие места в приложениях.
Возможности профилирования
В Visual Studio 2013, существующие ранее возможности профилирования Windows Store приложений и новые, добавленные возможности, были перенесены в специальный визард Performance and Diagnostics Hub. Он позволяет разработчикам собирать данные и осуществлять анализ использования аппаратных ресурсов, производительности интерфейса и кода приложения.
Найти его вы можете в меню Debug или Analyze.
Итак, вам доступны следующие возможности:
- CPU Sampling. Сбор данных о использовании CPU.
- Energy Consumption. Сбор статистики энергопотребления, что особенно актуально для RT устройств, без использования какого-либо дополнительного железа.
- HTML UI Responsiveness. Сбор статистики по времени отклика страниц и элементов управления для HTMLJavaScript приложений.
- XAML UI Responsiveness. Сбор статистики по времени отклика страниц и элементов управления для XAMLC# приложений.
- JavaScript Memory. Сбор статистики по использованию памяти. Позволяет находить утечки памяти в JavaScript приложениях.
- JavaScript Function timing. Отображает информацию о времени выполнения JavaScript функций.
- Performance Wizard. По-прежнему существует. Используется, в основном, для профилирования классических клиентских приложений или ASP.NET приложений.
Вы можете профилировать не только открытое в студии приложение, но и любое другое, установленное приложение, а так же, ASP.NET приложение или exe файл.
Если вы выбираете уже установленное приложение, то вам предоставляется возможность профилировать его не только на своем локальном компьютере, но и на любом другом доступном удаленном компьютере.
Профилирование Windows 8.1 приложений
Теперь давайте посмотрим как использовать и применять новые возможности для диагностики проблем с производительностью приложения.
Изучать возможности профилирования мы будем на примере простой игрушки BubblePopper.
Игрушка генерирует шарики, которые необходимо «давить» пока они не достигли «потолка».
Скачать исходный код для экспериментов можно тут: http://sdrv.ms/1bgyAwP
Использование CPU
Сбор данных
Откройте приложение BubblePopper в Visual Studio 2013. В верхнем меню выберите Analyze — Performance and Diagnostics. В открывшемся окне поставьте галочку CPU Sampling и нажмите кнопку Start.
Приложение запустится и начнется сбор данных.
Используйте приложение минуту или чуть больше, а затем остановите отладку и сбор данных.
Анализ
После того, как анализ и обработка данных будут завершены, откроется отчет, содержащий следующие информационные блоки:
- CPU chart: показывает процент использования процессора приложением. Когда мы активно «давили» шарики, процессор используется чуть больше, когда менее активно – чуть меньше. По отчету видно, что проблем и резких пиков у нас нет.
- Hot path: отображает call stack приложения и время выполнения методов.
- Functions doing the most individual work: функции, на которые было потрачено больше всего процессорного времени.
Ничего криминального, скажете вы. Если вы обратите внимание, метод MainPage.moveBubble_Completed выполнялся дольше остальных и даже отмечен специальной иконкой с огоньком. Нажмите на него. Вы перейдете на отчет Function Details.
Function Details, на мой взгляд, самая полезная часть CPU отчета. Отчет показывает откуда вызывается наш метод и кого он вызывает. Но самое интересное – это то, что он показывает какие именно строчки вашего кода выполняются дольше всего. Это позволит вам целенаправленно работать и оптимизировать только самые медленные части кода, не тратя много времени на поиски.
Энергопотребление
Сбор данных
Откройте приложение BubblePopper в Visual Studio 2013. В Solution Explorer откройте файл MainPage.xaml.cs и в методе moveBubble_Completed раскомментируйте вызов:
void moveBubble_Completed(object sender, object e)
{
…
OpenWebSite("http://microsoft.com");
}
Это позволит нам в тестовых целях генерировать http трафик, заметный на отчете.
Далее, верхнем меню выберите Analyze — Performance and Diagnostics.
В открывшемся окне поставьте галочку Energy Consumption и нажмите кнопку Start.
Приложение запустится и начнется сбор данных.
Используйте приложение минуту или чуть больше, а затем остановите отладку и сбор данных.
Анализ
После того, как анализ и обработка данных будут завершены, откроется отчет, содержащий информацию по использованию процессора, сети и батареи.
Наш отчет выглядит нормально, ничего критичного, но давайте проведем эксперимент и немного оптимизируем наш код, чтобы увидеть разницу.
Откройте файл MainPage.xaml и замените метод moveBubble_Completed на следующий:
void moveBubble_Completed(object sender, object e)
{
Storyboard oldStoryBoard = (Storyboard)sender;
Bubble bubble = (Bubble)bubbles[oldStoryBoard];
double? xTo = bubble.DestinationX;
double? yTo = bubble.DestinationY;
double nextX = BubbleResources.NextXPoint(xTo);
double nextY = BubbleResources.NextYPoint(yTo);
//Check to see if the buble is off the top of of the screen
if (yTo < 0 - bubble.BubbleEllipse.ActualHeight)
{
//Remove the old storyboard
bubbles.Remove(bubble.AnimationStoryboard);
//Remove the ellipse from the XAML tree
LayoutRoot.Children.Remove(bubble.BubbleEllipse);
return;
}
bubble.XAnimation.From = bubble.DestinationX;
bubble.XAnimation.To = nextX;
bubble.YAnimation.From = bubble.DestinationY;
bubble.YAnimation.To = nextY;
bubble.DestinationX = nextX;
bubble.DestinationY = nextY;
bubble.AnimationStoryboard.Begin();
}
Мы оптимизировали работу метода и убрали генерацию сетевой активности. Давайте заново запустим приложение и сбор данных Energy Consumption. В результате мы получим следующий отчет.
Как вы видите, использование сетевых ресурсов прекратилось, а так же сократилось использование батареи с 48% до 43% за счет оптимизации кода приложения.
Производительность UI
Сбор данных
Откройте приложение BubblePopper в Visual Studio 2013 (желательно открыть версию приложения без исправлений кода).
В верхнем меню выберите Analyze — Performance and Diagnostics. В открывшемся окне поставьте галочку XAML UI Responsiveness и нажмите кнопку Start. Если бы у нас было HTMLJavaScript приложение, то на этом месте была бы настройка HTML UI Responsiveness.
Приложение запустится и начнется сбор данных.
Используйте приложение минуту или чуть больше, а затем остановите отладку и сбор данных.
Анализ
После того, как анализ и обработка данных будут завершены, откроется отчет, содержащий информацию по времени загрузки страниц, элементов управления и выполнению кода. Всё это в привязке к жизненному циклу приложения.
В отчете можно заметить, что на выполнения кода приложения тратится очень много ресурсов, по сравнению с интерфейсом.
Проведем эксперимент и оптимизируем наш код так же, как и в прошлом примере.
Откройте файл MainPage.xaml и замените метод moveBubble_Completed на следующий:
void moveBubble_Completed(object sender, object e)
{
Storyboard oldStoryBoard = (Storyboard)sender;
Bubble bubble = (Bubble)bubbles[oldStoryBoard];
double? xTo = bubble.DestinationX;
double? yTo = bubble.DestinationY;
double nextX = BubbleResources.NextXPoint(xTo);
double nextY = BubbleResources.NextYPoint(yTo);
//Check to see if the buble is off the top of of the screen
if (yTo < 0 - bubble.BubbleEllipse.ActualHeight)
{
//Remove the old storyboard
bubbles.Remove(bubble.AnimationStoryboard);
//Remove the ellipse from the XAML tree
LayoutRoot.Children.Remove(bubble.BubbleEllipse);
return;
}
bubble.XAnimation.From = bubble.DestinationX;
bubble.XAnimation.To = nextX;
bubble.YAnimation.From = bubble.DestinationY;
bubble.YAnimation.To = nextY;
bubble.DestinationX = nextX;
bubble.DestinationY = nextY;
bubble.AnimationStoryboard.Begin();
}
Заново запустите приложение и сбор данных XAML UI Responsiveness. В результате получим следующий отчет.
По отчету видно, что код стал работать существенно быстрее.
В этом отчете есть еще одна полезная возможность. Просмотр статистики выполнения страниц и элементов управления. Для просмотра статистики необходимо нажать на ссылку Parsing.
В этом представлении удобно искать не оптимально работающие элементы управления и компоненты.
Кстати, это еще не все возможности Performance and Diagnostics Hub, но основные и самые применимые и полезные.
Заключение
В данной статье мы сосредоточились на возможностях профилирования и анализа производительности Windows Store приложений в VisualStudio 2013, таких как:
- Использование CPU.
- Энергопотребление.
- Производительность UI.
Я надеюсь, эта информация поможет вам познакомиться и начать использовать возможности VisualStudio 2013 для улучшения производительности ваших Windows Store приложений.
Полезные материалы
Channel 9: Performance and Diagnostics Hub
Build 2013: Diagnosing Issues in JavaScript Windows Store Apps with Visual Studio 2013
Build 2013: Developing High Performance Websites and Modern Apps with JavaScript Performance Tools
Build 2013: Visual Studio 2013 Diagnostics Tools for XAML-Based Windows Store Apps
MSDN: Configure remote profiling on the remote device
Автор: MissUFO