blob: fc88cbd7cc328bc840a667207e82ed9e165a7280 [file] [log] [blame]
page.title=Тестирование скорости отображения
page.image=images/cards/card-test-performance_2x.png
page.keywords=скорость отображения, кадр/с, инструменты
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>Содержание документа</h2>
<ol>
<li><a href="#measure">Измерение производительности интерфейса</a>
<ul>
<li><a href="#aggregate">Агрегированные статические данные о кадрах</a></li>
<li><a href="#timing-info">Точная информация о кадровой синхронизации</a></li>
<li><a href="#timing-dump">Дамп простой кадровой синхронизации</a></li>
<li><a href="#collection-window">Управление промежутком времени для сбора статистических данных</a></li>
<li><a href="#diagnose">Диагностика снижения производительности</a></li>
<li><a href="#resources">Дополнительные ресурсы</a></li>
</ul>
</li>
<li><a href="#automate">Автоматизация тестирования производительности интерфейса</a>
<ul>
<li><a href="#ui-tests">Настройка тестов интерфейса</a></li>
<li><a href="#automated-tests">Настройка автоматизированного тестирования интерфейса</a></li>
<li><a href="#triage">Определение и устранение обнаруженных проблем</a></li>
</ul>
</li>
</ol>
</div>
</div>
<p>
Тестирование производительности интерфейса позволяет убедиться в том, что ваше приложение не только соответствует функциональным требованиям,
но и гарантирует пользователю безупречное взаимодействие с интерфейсом с постоянной частотой отображения
60 кадров в секунду (<a href="https://www.youtube.com/watch?v=CaMTIgxCSqU&amp;index=25&amp;list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">почему именно
60 кадров/с?</a>), без каких-либо задержек и пропущенных кадров или, как их называют, <em>глюков</em>. В этой
статье рассматриваются инструменты для измерения производительности интерфейса, а также предлагается подход к
интеграции этих процедур измерения производительности в ваши методы тестирования приложений.
</p>
<h2 id="measure">Измерение производительности интерфейса</h2>
<p>
Чтобы улучшить производительность, прежде всего у вас должна иметься возможность измерить производительность
вашей системы. Когда это сделано, необходимо диагностировать и определить проблемы, которые могут возникнуть на разных этапах
процесса разработки.
</p>
<p>
<em><a href="https://source.android.com/devices/tech/debug/dumpsys.html">dumpsys</a></em>
это инструмент Android, который запускается на устройстве и создает дамп интересной информации о состоянии системных
служб. После передачи в dumpsys команды <em>gfxinfo</em> в журнал устройства (logcat)
записываются сведения о производительности, касающиеся скорости анимации на этапе
записи.
</p>
<pre>
&gt; adb shell dumpsys gfxinfo &lt;PACKAGE_NAME&gt;
</pre>
<p>
Эта команда может создавать множество различных вариантов данных кадровой синхронизации.
</p>
<h3 id="aggregate">Агрегированные статические данные о кадрах</h3>
<p>
В M Preview эта команда фиксирует в logcat агрегированный анализ данных о кадрах, полученных
за весь жизненный цикл процесса. Например:
</p>
<pre class="noprettyprint">
Stats since: 752958278148ns
Total frames rendered: 82189
Janky frames: 35335 (42.99%)
90th percentile: 34ms
95th percentile: 42ms
99th percentile: 69ms
Number Missed Vsync: 4706
Number High input latency: 142
Number Slow UI thread: 17270
Number Slow bitmap uploads: 1542
Number Slow draw: 23342
</pre>
<p>
Приведенные выше статистические данные высокого уровня демонстрируют производительность отрисовки, которой обладает приложение,
а также ее стабильность при обработке множества кадров.
</p>
<h3 id="timing-info">Точная информация о кадровой синхронизации</h3>
<p>
В M Preview представлена новая команда для gfxinfo <em>framestats</em>. Она позволяет получить
чрезвычайно точную информацию о кадровой синхронизации из последних кадров, что поможет вам отслеживать проблемы
и устранять их.
</p>
<pre>
&gt;adb shell dumpsys gfxinfo &lt;PACKAGE_NAME&gt; framestats
</pre>
<p>
Данная команда предоставляет информацию о кадровой синхронизации буквально по наносекундам на основании последних 120
кадров, созданных приложением. Ниже приводится пример необработанного результата из журнала adb после выполнения команды dumpsys gfxinfo
&lt;PACKAGE_NAME&gt; framestats:
</p>
<pre class="noprettyprint">
0,49762224585003,49762241251670,9223372036854775807,0,49762257627204,49762257646058,49762257969704,49762258002100,49762265541631,49762273951162,49762300914808,49762303675954,
0,49762445152142,49762445152142,9223372036854775807,0,49762446678818,49762446705589,49762447268818,49762447388037,49762453551527,49762457134131,49762474889027,49762476150120,
0,49762462118845,49762462118845,9223372036854775807,0,49762462595381,49762462619287,49762462919964,49762462968454,49762476194547,49762476483454,49762480214964,49762480911527,
0,49762479085548,49762479085548,9223372036854775807,0,49762480066370,49762480099339,49762481013089,49762481085850,49762482232152,49762482478350,49762485657620,49762486116683,
</pre>
<p>
Каждая строка здесь представляет собой кадр, созданный приложением. В каждой строке имеется фиксированное количество
столбцов, где указано время, затраченное на каждом этапе процесса создания кадра. Более подробно этот формат рассматривается в следующем разделе,
включая сведения о том, что означает каждый столбец.
</p>
<h4 id="fs-data-format">Формат данных, возвращаемых командой framestats</h4>
<p>
Поскольку блок данных выводится в формате CSV, вы можете с легкостью вставить его в любую программу
для работы с электронными таблицами, а также собрать и обработать данные с помощью сценария. Ниже рассматривается формат
столбцов выходных данных. Все временные метки указаны в наносекундах.
</p>
<ul>
<li>FLAGS
<ul>
<li>В строках, в которых в столбце FLAGS указано «0», общее время смены кадра вычислялось путем
вычитания значения в столбце INTENDED_VSYNC из значения в столбце FRAME_COMPLETED.
</li>
<li>Если это значение не равно нулю, то строку следует пропустить, поскольку кадр был определен как отличающийся от
обычной производительности, при которой ожидается, что размещение и прорисовка кадра займут
больше 16 мс. Причина этого может заключаться в следующем:
<ul>
<li>макет окна был изменен (например, первый кадр приложения или после
вращения);
</li>
<li>также, возможно, кадр был пропущен, в результате чего временные метки некоторых значений
содержат бессмысленную информацию; кадр можно пропустить, если, например, скорость отображения превышает 60 кадров/с или если
на экране от этого не появяются шумы; это не обязательно указывает на проблему
в приложении.
</li>
</ul>
</li>
</ul>
</li>
<li>INTENDED_VSYNC
<ul>
<li>Предполагаемая начальная точка кадра. Если данное значение отличается от значения в столбце VSYNC, это указывает на то,
что поток был занят и не смог своевременно среагировать на сигнал
vsync.
</li>
</ul>
</li>
<li>VSYNC
<ul>
<li>Значение времени, которое использовалось во всех приемниках vsync, а также которое было затрачено на прорисовку кадра
(обратные вызовы кадров Choreographer и анимации, View.getDrawingTime() и т. д.)
</li>
<li>Чтобы узнать подробнее о VSYNC и о том, какое значение это имеет для вашего приложения, просмотрите
видеоролик,
<a href="https://www.youtube.com/watch?v=1iaHxmfZGGc&amp;list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&amp;index=23">посвященный общим сведениям о VSYNC</a>.
</li>
</ul>
</li>
<li>OLDEST_INPUT_EVENT
<ul>
<li>Временная метка для самого старого события ввода в очереди ввода или Long.MAX_VALUE, если
для кадра отсутствуют события ввода.
</li>
<li>Это значение в первую очередь предназначено для платформы и имеет ограниченную практическую ценность для разработчиков
приложений.
</li>
</ul>
</li>
<li>NEWEST_INPUT_EVENT
<ul>
<li>Временная метка для самого нового события ввода в очереди ввода или 0, если
для кадра отсутствуют события ввода.
</li>
<li>Это значение в первую очередь предназначено для платформы и имеет ограниченную практическую ценность для разработчиков
приложений.
</li>
<li>Однако оно позволяет получить приблизительное представление о том, какая задержка возникает у приложения,
обратившись к значению разницы (FRAME_COMPLETED - NEWEST_INPUT_EVENT).
</li>
</ul>
</li>
<li>HANDLE_INPUT_START
<ul>
<li>Временная метка отправки событий ввода в приложение.
</li>
<li>Разность между этим значением и значением ANIMATION_START позволяет определить,
сколько времени было затрачено приложением на обработку событий ввода.
</li>
<li>Если разность достаточно велика (&gt;2 мс), это означает, что приложение затрачивает очень
много времени на обработку событий ввода, таких как View.onTouchEvent(). В свою очередь, это может указывать на
необходимость оптимизации этого процесса обработки или переноса этой нагрузки в другой поток. Следует помнить, что существуют
сценарии, когда такое
поведение ожидается и является приемлемым. Имеются в виду нажатия или аналогичные сценарии, в которых запускаются новые операции.
</li>
</ul>
</li>
<li>ANIMATION_START
<ul>
<li>Временная метка запуска анимаций, зарегистрированных с помощью Choreographer.
</li>
<li>Разность между этим значением и PERFORM_TRANVERSALS_START позволяет
определить, сколько времени потребовалось на оценку всех запущенных аниматоров (ObjectAnimator,
ViewPropertyAnimator и общих переходов).
</li>
<li>Если разность достаточно велика (&gt;2 мс), проверьте наличие в приложении настраиваемых
аниматоров, а также то, какие поля анимируют классы ObjectAnimator. Убедитесь, что
эти поля подходят для анимации.
</li>
<li>Чтобы узнать подробнее о Choreographer, просмотрите видео <a href="https://developers.google.com/events/io/sessions/325418001">For Butter or Worse</a>.
</li>
</ul>
</li>
<li>PERFORM_TRAVERSALS_START
<ul>
<li>Если вычесть значение DRAW_START из этого значения, вы можете узнать, сколько времени было затрачено на разметку и
измерение. (Обратите внимание, что во время прокрутки или анимации это значение должно быть близко
к нулю.)
</li>
<li>Чтобы узнать подробнее об этапах разметки и измерения во время рендеринга интерфейса приложения, просмотрите
видео, посвященное
<a href="https://www.youtube.com/watch?v=we6poP0kw6E&amp;list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&amp;index=27">аннулированию, макетам и производительности</a>.
</li>
</ul>
</li>
<li>DRAW_START
<ul>
<li>Время начала этапа отрисовки с помощью метода performTraversals. Это точка начала
записи списков отображения любых представлений, которые были аннулированы.
</li>
<li>Разность между этим значением и значением SYNC_START означает, сколько времени потребовалось на вызов метода View.draw() для всех
аннулированных представлений в дереве.
</li>
<li>Дополнительные сведения о модели отрисовки представлены в видео, посвященном <a href="{@docRoot}guide/topics/graphics/hardware-accel.html#hardware-model">аппаратному ускорению</a>
или
<a href="https://www.youtube.com/watch?v=we6poP0kw6E&amp;list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&amp;index=27">аннулированию, макетам и производительности</a>.
</li>
</ul>
</li>
<li>SYNC_START
<ul>
<li>Время начала этапа синхронизации отрисовки.
</li>
<li>Если разность между этим значением и значением ISSUE_DRAW_COMMANDS_START достаточно велика (&gt;0,4 мс или около этого),
обычно это указывает на наличие большого количество новых растровых изображений, которые следует передать
ЦП.
</li>
<li>Чтобы узнать подробнее об этапе синхронизации, просмотрите видео, посвященное
<a href="https://www.youtube.com/watch?v=VzYkVL1n4M8&amp;index=24&amp;list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu">рендерингу профиля с помощью ЦП</a>.
</li>
</ul>
</li>
<li>ISSUE_DRAW_COMMANDS_START
<ul>
<li>Время начала отправки аппаратным обработчиком команд на отрисовку для ЦП.
</li>
<li>Разность между этим значением и значением FRAME_COMPLETED позволяет получить приблизительное представление об объеме ресурсов ЦП, используемых
приложением. Здесь отображаются такие проблемы, как превышение или недостаток эффектов рендеринга.
</li>
</ul>
</li>
<li>SWAP_BUFFERS
<ul>
<li>Время вызова eglSwapBuffers;
относится к работе платформы и имеет ограниченную практическую ценность для разработчиков приложений.
</li>
</ul>
</li>
<li>FRAME_COMPLETED
<ul>
<li>Все готово! Общее время, затраченное на обработку этого кадра, вычисленное по следующей формуле:
FRAME_COMPLETED - INTENDED_VSYNC.
</li>
</ul>
</li>
</ul>
<p>
Эти данные можно использовать несколькими способами. Простым, но полезным примером может служить
график, иллюстрирующий распределение времени кадров (FRAME_COMPLETED - INTENDED_VSYNC) в
различных диапазонах задержки (см. рисунок ниже). На графике ясно видно, что с большинством кадров
никаких проблем не возникло (ниже отметки в 16 мс; обозначено красным), однако для некоторых кадров
это значение значительно превышено. Можно обратиться к этому графику и пронаблюдать изменения по времени,
чтобы увидеть общую картину смещения или новые отличающиеся значения. Также можно создать график задержи ввода,
времени, затраченного на разметку или других интересующих вас показателей, руководствуясь множеством временных меток,
имеющихся в данных.
</p>
<img src="{@docRoot}preview/images/perf-test-framestats.png">
<h3 id="timing-dump">Дамп простой кадровой синхронизации</h3>
<p>
Если в разделе настроек для разработчиков для параметра <strong>Profile GPU rendering</strong> задано значение <strong>In adb shell dumpsys gfxinfo</strong>,
команда <code>adb shell dumpsys gfxinfo</code> выдает сведения о синхронизации
по времени для последних 120 кадров. При этом вы увидите несколько категорий значений,
разделенные знаком табуляции. Эти данные могут оказаться полезными для определения частей конвейера отрисовки, которые могут работать с задержкой
при высоком уровне обработки.
</p>
<p>
Как и в случае с командой
<a href="#fs-data-format">framestats</a>, описанной выше, вы можете с легкостью вставить полученные данные в любую программу
для работы с электронными таблицами, а также собрать и обработать их с помощью сценария. На графике ниже иллюстрируется разбивка со сведениями о количестве созданных кадров и времени, которое приложение затратило на
это.
</p>
<img src="{@docRoot}preview/images/perf-test-frame-latency.png">
<p>
Результаты выполнения команды gfxinfo, копирования полученного результата, передачи его в приложение для работы
с электронными таблицами и построения графика представлены в виде столбцов.
</p>
<p>
Каждый столбец представляет собой один кадр анимации; его высота обозначает количество миллисекунд,
затраченных на вычисление этого кадра. Каждый цветной сегмент столбца
обозначает различный этап процесса рендеринга, что позволяет определить проблемные компоненты
приложения в плане производительности. Дополнительные сведения о
процессе рендеринга, а также о том, как оптимизировать его, представлены в видео, посвященном
<a href="https://www.youtube.com/watch?v=we6poP0kw6E&amp;index=27&amp;list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">аннулированию, макетам и производительности</a>.
</p>
<h3 id="collection-window">Управление промежутком времени для сбора статистических данных</h3>
<p>
При выполнении команды framestats, равно как и при вычислении простой кадровой синхронизации, данные собираются за достаточно короткий промежуток времени – порядка
двух секунд рендеринга. Чтобы точно указать этот промежуток времени (например,
чтобы ограничить данные определенной анимацией), можно сбросить все счетчики
и объединить собранные статистические данные.
</p>
<pre>
&gt;adb shell dumpsys gfxinfo &lt;PACKAGE_NAME&gt; reset
</pre>
<p>
Это также можно сделать совместно с выполнением самих команд создания дампа, чтобы выполнять сбор
и сброс регулярно, непрерывно получая данные за промежутки времени продолжительностью менее двух секунд.
</p>
<h3 id="diagnose">Диагностика снижения производительности</h3>
<p>
Определение снижений производительности послужит отличным началом для отслеживания проблем, а также позволит всегда поддерживать
хорошую работоспособность приложения. Однако инструмент dumpsys позволяет лишь определить наличие проблем и приблизительный уровень их
серьезности. Вам же требуется диагностировать каждую конкретную проблему с
производительностью и найти подходящие способы ее устранения. Для этих целей прекрасно
подходит инструмент <a href="{@docRoot}tools/help/systrace.html">systrace</a>.
</p>
<h3 id="resources">Дополнительные ресурсы</h3>
<p>
Дополнительные сведения о принципе работы конвейера рендеринга платформы Android, информация об общих проблемах, с которыми можно столкнуться при его использовании,
а также способы их устранения представлены на указанных ниже
полезных ресурсах.
</p>
<ul>
<li>Производительность визуализации 101
</li>
<li>Частота 60 кадров в секунду
</li>
<li>Пользовательский интерфейс Android и графический процессор
</li>
<li>Аннулирование макетов и производительность
</li>
<li>Анализ производительности интерфейса с помощью systrace
</li>
</ul>
<h2 id="automate">Автоматизация тестирования производительности интерфейса</h2>
<p>
Один из подходов к тестированию производительности интерфейса заключается в простом привлечении тестировщиков, чтобы они выполнили ряд
операций с целевым приложением, а также либо просто визуально убедились в отсутствии глюков, либо уделили достаточно много времени
тестированию приложения с помощью соответствующего инструмента. Однако такой подход имеет один важный недостаток
человек физически не способен обрабатывать информацию при очень быстрой смене кадров.
Кроме того, такая работа занимает много времени, утомляет и не гарантирует полное отсутствие ошибок.
</p>
<p>
Гораздо эффективнее записать ключевые показатели производительности, полученные в ходе автоматического
тестирования интерфейса, и проанализировать их. В состав Android M Developer Preview входят новые функции ведения журналов, которые позволяют с легкостью
определить объем и серьезность глюков анимации в приложении.
Их также можно использовать для того, чтобы создать строгий процесс определения текущей производительности и отслеживать соответствие требованиям будущих задач
производительности.
</p>
<p>
В этой статье мы расскажем вам, как мы рекомендуем использовать такие данные, чтобы автоматизировать
тестирование производительности.
</p>
<p>
Этот подход большей частью сводится к двум ключевым шагам. Шаг первый: определите, что вы
тестируете и как вы это делаете. Шаг второй: произведите настройку
среды автоматизированного тестирования и ее обслуживание.
</p>
<h3 id="ui-tests">Настройка тестов интерфейса</h3>
<p>
Прежде чем приступить к автоматизированному тестированию, необходимо принять ряд важных решений,
чтобы правильно определить область тестирования и ваши требования.
</p>
<h4>
Определение ключевых анимаций или потоков для тестирования
</h4>
<p>
Помните, что плохая производительность чаще всего выражается для пользователей в отсутствии плавной
анимации. Поэтому при определении того, какие типы действий в пользовательском интерфейсе следует протестировать, полезно
сосредоточить внимание на ключевых анимациях, наиболее важных для
взаимодействия пользователя с приложением. Ниже представлены примеры наиболее распространенных сценариев, которые может оказаться полезным определить.
</p>
<ul>
<li>Прокрутка основного представления ListView или RecyclerView
</li>
<li>Анимации во время циклов асинхронного ожидания
</li>
<li>Любые анимации, включающие загрузку растровых изображений или манипуляции с ними
</li>
<li>Анимации, включающие смешивание альфа-канала
</li>
<li>Отрисовка настраиваемого представления на экране
</li>
</ul>
<p>
Определите, какие из этих
ключевых анимаций следует протестироваит в первую очередь. При принятии решения подключите инженеров, дизайнеров и менеджеров по продукту.
</p>
<h4>
Определите свои будущие задачи и отслеживайте их выполнение
</h4>
<p>
С профессиональной точки зрения, может оказаться крайне важным решить, каких именно показателей производительности вы хотите добиться, и
сосредоточить усилия на создании необходимых тестов и сборе соответствующих данных. Например:
</p>
<ul>
<li>Вы только хотите начать отслеживание производительности интерфейса, чтобы получить дополнительные сведения?
</li>
<li>Вы хотите предотвратить возможно снижение производительности в будущем?
</li>
<li>На сегодняшний день 90% кадров анимируются плавно. Вы хотите увеличить этот показатель до 98% в этом квартале?
</li>
<li>На сегодняшний день 98% кадров анимируются плавно. Вы не хотите, чтобы производительность снизилась?
</li>
<li>Вы хотите улучшить производительность на бюджетных устройствах?
</li>
</ul>
<p>
Во всех перечисленных случаях вам потребуется хронологическое отслеживание показателей, демонстрирующих производительность
разных версий вашего приложения.
</p>
<h4>
Определение устройств для тестирования
</h4>
<p>
Производительность приложения может меняться в зависимости от того, на каком устройстве оно установлено. Некоторые устройства могут обладать недостаточным
объемом памяти, менее производительными графическими процессорами или слабыми ЦП. Это означает, что анимации,
которые прекрасно работают на устройстве с одним оборудованием, могут вообще не работать на устройстве с другим оборудованием, и, что хуже всего, препятствовать
нормальной работе другой части конвейера. Поэтому, учитывая такую разницу
в отображении интерфейса для пользователей, выберите диапазон устройств для выполнения тестов, включив в него
как современные высокотехнологичные, так и бюджетные устройства, планшеты и т. д. При выборе диапазона устройств учитывайте разницу в производительности ЦП
, ОЗУ, разрешение экрана, его размер и т. д. Тесты, которые успешно прошли на устройстве верхнего ценового сегмента,
могут завершиться сбоем на бюджетных моделях.
</p>
<h4>
Базовые средства для тестирования пользовательского интерфейса
</h4>
<p>
Такие наборы инструментов, как <a href="{@docRoot}training/testing/ui-testing/uiautomator-testing.html">UI Automator</a> и
<a href="{@docRoot}training/testing/ui-testing/espresso-testing.html">Espresso</a>,
призваны помочь автоматизировать действия пользователей при взаимодействии с вашим приложением. Это простые инструменты,
имитирующие работу пользователя на устройстве. Для использования этих инструментов
вам необходимо создать уникальные сценарии, которые будут включать выполнение ряда действий, и воспроизвести
их на устройстве.
</p>
<p>
Используя эти автоматизированные тесты в сочетании с командой <code>dumpsys gfxinfo</code>, вы можете быстро создать
воспроизводимую систему, позволяющую выполнять тестирование и анализировать
полученную информацию о производительности для каждого определенного условия.
</p>
<h3 id="automated-tests">Настройка автоматизированного тестирования интерфейса</h3>
<p>
Получив возможность протестировать интерфейс, а также настроив конвейер на сбор результатов
отдельного теста, важно выбрать инструмент, который позволит многократно выполнить
тест на нескольких устройствах, а также объединить данные о результатах
тестирования производительности для их дальнейшего анализа вашими специалистами по разработке.
</p>
<h4>
Инструмент для автоматизации тестирования
</h4>
<p>
Следует отметить, что инструменты для тестирования интерфейса (такие как <a href="{@docRoot}training/testing/ui-testing/uiautomator-testing.html">UI Automator</a>)
можно запускать прямо на целевом устройстве или в эмуляторе. Тогда как сбор командой
<em>dumpsys gfxinfo</em> информации о производительности выполняется на хост-компьютере, который отправляет команды из ADB. Чтобы объединить
усилия этих двух инструментов, был разработан <a href="{@docRoot}tools/help/monkeyrunner_concepts.html">MonkeyRunner</a>.
Эта система написания сценариев, работающая на хост-компьютере, отправляет команды на
подключенные устройства, а также получает данные от них.
</p>
<p>
Набор сценариев для надлежащей автоматизации тестирования производительности интерфейса должен включать использование
системы MonkeyRunner хотя бы для выполнения следующих задач:
</p>
<ul>
<li>загрузка и запуск на целевые устройства или в эмулятор необходимого пакета APK;
</li>
<li>запуск теста UI Automator и его выполнение;
</li>
<li>сбор информации о производительности с помощью <em>dumpsys gfxinfo</em><em>;</em>
</li>
<li>объединение полученной информации и ее отображение для разработчика в удобочитаемой форме.
</li>
</ul>
<h3 id="triage">Определение и устранение обнаруженных проблем</h3>
<p>
После обнаружения проблемных мест или причин снижения производительности необходимо понять, что должно быть исправлено
и внести соответствующие изменения. Если используемый инструмент для автоматизированного тестирования обеспечивает соблюдение точной разбивки
кадровой синхронизации по времени, то с его помощью можно тщательно изучить недавние подозрительные изменения в коде или макете случае
со снижением производительности), а также ограничить область системы, которая подлежит анализу, когда вы переключаетесь на изучение проблемы
вручную. В последнем случае прекрасно подойдет <a href="{@docRoot}tools/help/systrace.html">systrace</a>. С помощью этого инструмента вы можете получить подробнейшую информацию
о синхронизации относительно каждого этапа конвейера рендеринга, относительно каждого потока и каждого ядра
системы, а также относительно любых настраиваемых маркеров событий, которые вы задаете.
</p>
<h4>
Надлежащее профилирование синхронизации по времени
</h4>
<p>
Важно отметить трудности, с которыми можно столкнуться при получении и анализе данных синхронизации, связанных
с производительностью визуализации. Результаты по своей природе недетерминированные и зачастую
изменяются в зависимости от состояния системы, объема доступной памяти, температурного
дросселирования и времени суток. Смысл в том, что
вы можете выполнить один и тот же тест дважды и получить результаты,
которые будут похожи, но не совпадут в точности.
</p>
<p>
Правильный сбор и профилирование данных означает выполнение одного и того же теста
несколько раз и накопление результатов для вычисления среднего значения (для простоты назовем это
пакетом результатов). Это позволяет получить приблизительное представление о производительности
теста, когда нет необходимости в точных данных.
</p>
<p>
Пакеты можно использовать при изучении изменений кода, чтобы увидеть их относительное влияние на
производительность. Если средняя частота кадров для пакета результатов, полученных до изменения, больше значения для пакета, полученного
после изменения, обычно вы получаете общее повышение производительности в результате этого конкретного
изменения.
</p>
<p>
При выполнении любого автоматизированного тестирования интерфейса следует учитывать этот момент,
равно как и любые аномалии, которые могут возникнуть во время теста. Например,
если производительность вашего приложения неожиданно резко падает из-за проблем с оборудованием устройства (которые
не вызваны вашим приложением), возможно, вы захотите выполнить пакет повторно, чтобы получить
менее беспорядочные данные о синхронизации.
</p>
<p>
Итак, сколько раз следует выполнять тест, прежде чем его результаты станут значимыми? Не менее 10!
Чем больше раз вы выполняете тест (например, можно сделать 50100 прогонов), тем выше точность результатов
(хотя, конечно, ради точности приходится поступаться временем).
</p>