Документация
ОС Аврора 5.1.4

Профилирование QML-приложений

Типичные проблемы производительности приложения

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

К причинам снижения скорости работы пользовательского интерфейса можно отнести:

  • Выполнение большого количества JavaScript-кода при малом количестве кадров. Весь JavaScript-код должен завершиться прежде, чем GUI-поток сможет продолжить работу. Если GUI-поток не готов, то кадры задерживаются или отбрасываются.
  • Создание, отрисовка или обновление невидимых элементов, которые также занимают время в GUI-потоке.

Для поиска чрезмерного использования JavaScript-кода, следует проверить частоту кадров в анимациях и событиях Scene Graph, найти разрывы и проверить, ведёт ли себя приложение так, как задумано. Категория событий JavaScript в QML-профайлере отображает время выполнения функций, которое рекомендуется держать ниже 16 мс на кадр.

Если кадры отбрасываются, когда JavaScript код не выполняется, и на временной шкале присутствуют разрывы, то следует проверить реализацию пользовательского QQuickItem.

Для проверки производительности C++-функций, выполняющих рисование и обработку сигналов, можно использовать утилиты MemCheck и CallGrind, входящие в состав профайлера Valgrind, или другие инструменты профилирования общего назначения.

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

Для проверки макета сцены и поиска элементов, которые всегда невидимы для пользователя, так как они расположены за пределами экрана или скрыты под другими видимыми элементами, можно визуализировать прорисовку Scene Graph

Использование QML-профайлера

QML-профайлер можно использовать как на эмуляторе, так и на устройстве. Для работы с профайлером на устройстве требуется отключить валидатор.

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

Для отслеживания производительности приложения с помощью QML-профайлера необходимо выполнить следующие шаги:

  1. Выбрать тип сборки Профилирование.
  2. Убедиться, что у проекта включена возможность QML-отладки (по умолчанию QML-отладка включена):
    1. Переключить Аврора IDE в режим Проекты.
    2. Выбрать пункт Сборка целевого комплекта.
    3. Убедиться, что в разделе Отладка и профилирование QML → Основное установлено значение Включить.
  3. Запустить профилирование в меню Анализ, выбрав пункт Профайлер QML.

С запуском профилирования включается приложение и  QML-профайлер начинает собирать данные. Об этом свидетельствует время в поле Прошло.

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

Данные будут отправлены в QML-профайлер после нажатия на кнопку Отключить профилирование, поэтому не следует использовать команды приложения для завершения его работы. Приложение продолжит работать несколько секунд и остановится автоматически. При выходе из приложения другим способом данные не отправятся в Аврора IDE.

Для включения автоматического сбора данных следует нажать кнопку Включить профилирование.

Для отключения сбора данных следует нажать на кнопку Отключить профилирование до запуска приложения.

Собранные данные следует сохранить, используя меню Анализ → Настройки профайлера QML → Сохранить трассировку QML. Для просмотра данных следует использовать меню Анализ → Настройки профайлера QML → Загрузить трассировку QML.

Пункт меню Загрузить трассировку QML позволяет загружать данные полученные от других разработчиков.

Настройки передачи данных

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

Для общих настроек следует использовать меню Инструменты → Параметры → Анализатор → Профайлер QML.

Для указания пользовательских настроек для определённого проекта необходимо переключить Аврора IDE в режим Проекты, далее Запуск целевой сборки → Настройки профайлера QML и установить значение Особые.

Для восстановления общих настроек для проекта следует нажать на кнопку Восстановить общие.

Настройки профайлера QML для проекта

Для экономии памяти на целевом устройстве и сокращения времени обработки передаваемых данных можно установить флаг Передавать данные при профилировании, чтобы результаты порциями передавались в Аврора IDE во время профилирования. Интервал передачи данных можно регулировать с помощью поля Интервал передачи.

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

Анализ данных

Вкладка Временная шкала показывает графическое представление выполнения QML и JavaScript-кода, а также сжатое представление всех записанных событий.

Временная шкала

Каждая строка временной шкалы (6) описывает тип QML-событий, которые были записаны. Для анализа времени и моментов вызова событий следует навести курсор мыши на событие в строке. Чтобы информация отображалась только тогда, когда событие выбрано, следует использовать переключатель Показывать информацию о событии при наведении курсора (4).

Шкала (10) кратко описывает период, за который были собраны данные. Для управления диапазоном масштабирования (8) следует использовать контур для перемещения по шкале (9). Переход между событиями осуществляется с помощью кнопок Перейти к предыдущему событию (1) и Перейти к следующему событию(1).

Для включения ползунка установки уровня масштабирования следует нажать на кнопку Показать ползунок масштабирования (2). Для сброса уровня масштабирования к значению по умолчанию следует кликнуть правой кнопкой мыши по временной шкале и в контекстном меню выбрать пункт Сбросить масштаб.

Для добавления вертикальных ориентационных линии (5) на временную шкалу следует кликнуть по временной линейке.

Выбор диапазонов событий

Для просмотра частот кадров событий и сравнения её с частотой кадров похожих событий, нужно выбрать диапазон событий (7). Кнопка Выбрать диапазон (3), служит для активации инструмента выделения. Потом следует кликнуть на временную шкалу, чтобы указать начало диапазона событий. Нужно переместить ручку выделения, чтобы определить конец диапазона. Длина диапазона показывает частоту кадров события.

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

Для увеличения диапазона событий следует дважды кликнуть по нему.

Чтобы сузить текущий диапазон на вкладках Временная шкала, Статистика и Flame Graph, нужно кликнуть правой кнопкой мыши по диапазону и выбрать Анализировать текущий диапазон. Чтобы вернуться к полному диапазону, следует нажать на Анализировать полный диапазон в контекстном меню.

Для удаления диапазона событий нужно закрыть диалог Выделение.

Описание данных

Обычно события на вкладке временной шкалы показывают, сколько времени заняло выполнение QML или JavaScript-кода. Для просмотра подробностей достаточно навести курсор мыши на событие. При этом доступен просмотр части исходного кода, вызывающего событие.

В таблице перечислены типы событий, которые отображаются на вкладке временной шкалы. Доступность типов событий зависит от версии Qt, в которой было скомпилировано приложение, и от версии Qt Quick, которую оно использует.

Категория события Описание Минимальная версия Qt Версия Qt Quick
Animations Отображает количество активных анимаций и частоту кадров, с которой они работают. Информация об анимациях потока рендеринга отображается для приложений, построенных с помощью Qt 5.3 и более поздних версий. Анимации потока рендеринга показаны в отдельной строке. Qt 5.0 (Qt 5.3) Qt Quick 2
Binding Отображает время, когда оценивается привязка, и продолжительность оценки. Qt 4.7.4 Qt Quick 1 или Qt Quick 2
Compiling Отображает время, затраченное на компиляцию файлов QML. Qt 4.7.4 Qt Quick 1 или Qt Quick 2
Creating Отображает время, затраченное на создание элементов в сцене. В Qt Quick 2 создание элементов происходит в два этапа. На первом этапе создаются структуры данных, включая дочерние элементы. Второй этап представляет собой запуск завершающих методов обратного вызова. Однако не все элементы выполняют такой запуск. Этапы отображаются на временной шкале в виде отдельных событий. Для приложений Qt Quick 2, скомпилированных с помощью Qt версии 5.2.1 и ниже, показано только создание элементов верхнего уровня в виде отдельных событий. Qt 4.7.4 (Qt 5.2.1) Qt Quick 1 или Qt Quick 2
Handling Signal Отображает время обработки сигнала и продолжительность обработки. Qt 4.7.4 Qt Quick 1 или Qt Quick 2
Input Events Отображает события мыши и клавиатуры. Qt 4.7.4 Qt Quick 1 или Qt Quick 2
JavaScript Отображает время, затраченное на фактическое выполнение JavaScript-кода с привязками и обработчиками сигналов. В нём перечислены все JavaScript-функции, которые можно использовать, чтобы оценить привязки или обработки сигналов. Qt 5.3 Qt Quick 2
Memory Usage Отображает распределения блоков менеджера памяти JavaScript. Обычно менеджер памяти резервирует большие блоки памяти в один блок, а потом раздаёт его приложению более мелкими частями. Если приложение запрашивает отдельные блоки памяти, превышающие определённый размер, менеджер памяти выделит их отдельно. Эти два режима показаны в виде событий разных цветов. Во второй строке отображается фактическое использование выделенной памяти, объём, который приложение фактически запросило. Qt 5.4 Qt Quick 2
Painting Отображает время, затраченное на рисование сцены для каждого кадра. Qt 4.7.4 Qt Quick 1
Pixmap Cache Отображает общий объём кэшированных данных Pixmap в пикселях. А также отображает отдельное событие для каждого загружаемого изображения с указанием файла и размера. Qt 5.1 Qt Quick 2
Scene Graph Отображает время рендеринга кадров графа сцены и дополнительную информацию о времени для различных этапов, выполняемых для этого. Qt 5.1 Qt Quick 2

Анализ событий Scene Graph

Категория Scene Graph включает в себя несколько событий. При этом не все события генерируются циклами рендеринга.

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

Тип события Поток Типы циклов рендеринга Метка в выводе QSG_RENDER_TIMING Описание Примечание
Animations GUI Threaded, Windows animations Продвижение анимации в GUI-потоке. Основной цикл рендеринга не управляет анимацией синхронно с рендерингом. По этой причине события анимации не будут показаны, когда используется базовый цикл рендеринга. Чтобы увидеть время анимации, нужно следить за категорией Animations. Нет
Glyph Render Render Threaded, Basic, Windows glyphs ... rendering Рендеринг шрифтовых глифов в текстуры. Версии Qt до Qt 5.4 сообщают неправильное время для этих событий.
Glyph Upload Render Threaded, Basic, Windows glyphs ... upload Загрузка текстур глифов в GPU. Версии Qt до Qt 5.4 сообщают неправильное время для этих событий.
GUI Thread Sync GUI Threaded blockedForSync Время, в течение которого GUI-поток блокируется в ожидании потока рендеринга. Нет
GUI Thread Wait GUI Threaded lock Выполнение слотов, подключённых к сигналу QQuickWindow::afterAnimating(), и последующая блокировка мьютекса потока рендеринга перед ожиданием того же мьютекса в событии GUI Thread Sync. Если начинается задолго до Render Thread Sync, то в GUI потоке появляется свободное время, которое можно использовать для выполнения дополнительного QML или JavaScript кода. Нет
Material Compile Render Threaded, Basic, Windows shader compiled Компиляция программ шейдеров GLSL. Нет
Polish GUI Threaded, Basic, Windows polish Окончательная обработка элементов перед рендерингом с помощью QQuickItem::updatePolish(). Версии Qt до Qt 5.4 не регистрируют время события polish основного цикла рендеринга, а также регистрируют неправильное время цикла рендеринга окон.
Render Render Threaded, Basic, Windows Frame rendered ... render Общее время, потраченное на рендеринг кадра, включая подготовку и загрузку всех необходимых данных в GPU. Это грубое время рендеринга. Не следует путать его с чистым временем Render Render. В версиях Qt до Qt 5.5 общее время рендеринга и приведённое ниже разбиение времени рендеринга могут быть не согласованы на несколько микросекунд из-за того, что для их измерения используются разные, несинхронизированные таймеры. Например, может показаться, что Render Preprocess начинается до завершения Render Thread Sync.
Render Bind Render Threaded, Basic, Windows time in renderer ... binding Привязка правильного буфера кадра для рендеринга OpenGL. Является частью общего шага Render. Может быть неправильно согласован с Render в версиях Qt до Qt 5.5.
Render Preprocess Render Threaded, Basic, Windows time in renderer ... preprocess Вызов QSGNode::preprocess() на всех узлах, которые должны быть предобработаны. Является частью общего шага Render. Может быть неправильно согласован с Render в версиях Qt до Qt 5.5.
Render Render Render Threaded, Basic, Windows time in renderer ... rendering Фактический процесс отправки всех данных в GPU через OpenGL. Является частью общего шага Render. Может быть неправильно согласован с Render в версиях Qt до Qt 5.5.
Render Thread Sync Render Threaded, Basic, Windows Frame rendered ... sync Синхронизация QML-состояния с графом сцены с помощью QQuickItem::updatePaintNode(). Нет
Render Update Render Threaded, Basic, Windows time in renderer ... updates Итерация и обработка всех узлов в графе сцены для обновления их геометрии, трансформации, непрозрачности и других состояний. На этапе Render Thread Sync каждый узел обновляется отдельно с помощью состояния из GUI-потока. На этапе Render Update все узлы объединяются для создания окончательной сцены. Является частью общего шага Render. Может быть неправильно согласован с Render в версиях Qt до Qt 5.5.
Swap Render Threaded, Basic, Windows Frame rendered ... swap Подкачка кадров после рендеринга. Вывод времени подкачки, вызванный установкой QSG_RENDER_TIMING, некорректен для основного цикла рендеринга и версий Qt ниже Qt 5.4. QML-профайлер показывает правильное время подкачки.
Texture Bind Render Threaded, Basic, Windows plain texture ... bind Привязка текстуры в контексте OpenGL с помощью glBindTextures. Нет
Texture Convert Render Threaded, Basic, Windows plain texture ... convert Преобразование формата и уменьшение масштаба изображения, чтобы сделать его пригодным для использования в качестве текстуры. Нет
Texture Delete Render Threaded, Basic, Windows plain texture deleted Удаление текстуры с GPU, которая стала ненужной. Нет
Texture Mipmap Render Threaded, Basic, Windows plain texture ... mipmap Mip-отображение текстуры на GPU. Нет
Texture Swizzle Render Threaded, Basic, Windows plain texture ... swizzle При необходимости выполняется подмена текстурных данных на CPU. Нет
Texture Upload Render Threaded, Basic, Windows plain texture ... upload / atlastexture uploaded Загрузка данных текстуры в GPU. Нет

Просмотр статистики

На вкладке Статистика отображается количество срабатываний каждого события связывания, создания, компиляции, JavaScript или сигнала, а также среднее время, которое оно занимает. С помощью такого представления можно изучить события, которые требуют оптимизации. Например, высокое число вхождений может указывать на то, что событие срабатывает без необходимости. Для анализа медианного, наибольшего и наименьшего времени вхождений, следует выбрать Расширенная статистика событий в контекстном меню.

Для перехода к исходному коду, создающему событие, нужно кликнуть на событие.

Панели Вызывающие и Вызываемые показывают зависимости между событиями. Они позволяют исследовать внутренние функции приложения.

Панель Вызывающие суммирует QML-события, и указывает на те из них, которые вызвали изменение в привязке.

Панель Вызываемые суммирует QML-события, и указывает на те из них, которые будут затронуты, если привязка изменится.

При выборе события на вкладке Временная шкала будет отображена информация из вкладок Статистика и Flame Graph.

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

События JavaScript отображаются на вкладке Статистика, только если приложение использует Qt Quick 2 и скомпилировано с помощью Qt 5.3 или более поздней версии.

Визуализация статистики в Flame Graphs

Вкладка Flame Graphs показывает сжатый статистический обзор выполнения QML и JavaScript-кода. На вкладке Общее время горизонтальные полосы показывают сумму времени, которое заняли все вызовы конкретной функции относительно общего времени выполнения всех QML и JavaScript-событий. Вложенность показывает, какие функции были вызваны другими функциями.

Для просмотра общего объёма памяти, выделенного функциям, следует выбрать пункт Память в выпадающем меню.

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

В отличие от вкладки Шкала времени вкладка Flame Graphs не показывает промежутки времени, когда QML и JavaScript не выполняется. Поэтому Flame Graphs не подходит для анализа времени выполнения каждого кадра, но можно проанализировать общее влияние различных QML и JavaScript-событий.

Мы используем cookies для персонализации сайта и его более удобного использования. Вы можете запретить cookies в настройках браузера.

Пожалуйста ознакомьтесь с политикой использования cookies.