QML 애플리케이션 프로파일링
QML Profiler 를 사용하면 애플리케이션에서 발생하는 일반적인 성능 문제(예: 속도 저하, 응답 없음, 사용자 인터페이스 끊김 현상)의 원인을 파악할 수 있습니다. 일반적인 원인으로는 너무 적은 프레임 수에 비해 과도한 양의 JavaScript가 실행되는 경우가 있습니다. GUI 스레드가 다음 작업을 진행하기 위해서는 모든 JavaScript가 반환되어야 하며, GUI 스레드가 준비되지 않은 경우 프레임이 지연되거나 생략됩니다.
이와 유사한 성능 문제의 또 다른 일반적인 원인은 보이지 않는 항목을 생성하거나 업데이트하는 것으로, 이는 GUI 스레드에서 시간이 소요됩니다.
paint 메서드나 시그널 핸들러와 같이 실행 시간이 긴 C++ 함수를 호출하는 것도 GUI 스레드에서 시간을 소모하지만, QML Profiler 에서는 C++ 코드를 프로파일링하지 않기 때문에 이를 파악하기가 더 어렵습니다.
JavaScript의 과도한 사용을 확인하려면 애니메이션 및 씬 그래프 이벤트의 프레임 속도를 확인하고, 간격이 있는지 살펴보며, 애플리케이션이 예상대로 동작하는지 확인하십시오. JavaScript 카테고리에는 함수의 실행 시간이 표시되며, 이를 프레임당 16ms 미만으로 유지해야 합니다.
보이지 않는 항목을 처리하는 과정에서 발생하는 문제를 찾으려면 프레임 누락을 확인하고, 프레임마다 업데이트되는 짧은 바인딩이나 시그널 핸들러를 지나치게 많이 사용하고 있지 않은지 확인하십시오. 또한 씬 그래프 오버드로우를 시각화하여 씬 레이아웃을 확인하고, 화면 밖이나 다른 가시적인 요소 아래에 숨겨져 있어 사용자에게 절대 보이지 않는 항목을 찾아낼 수도 있습니다.
자바스크립트가 실행되지 않는데도 프레임이 누락되거나 타임라인에 설명할 수 없는 큰 간격이 있는 경우, 사용자 정의 ` QQuickItem ` 구현을 확인하세요. Valgrind Callgrind나 기타 범용 프로파일러를 사용하여 C++ 코드를 분석할 수 있습니다.
전체 스택 추적을 사용하여 최상위 QML 또는 자바스크립트에서 C++을 거쳐 커널 공간까지 추적할 수 있습니다. 수집된 데이터는 Chrome Trace Format Viewer에서 확인할 수 있습니다.
수집된 데이터 분석
Timeline 보기에서는 QML 및 JavaScript 실행을 그래픽으로 표시하고, 기록된 모든 이벤트의 요약된 보기를 제공합니다.

타임라인(6)의 각 행은 기록된 QML 이벤트의 유형을 나타냅니다. 행의 이벤트 위로 커서를 이동하면 해당 이벤트가 소요된 시간과 소스 코드의 어느 부분에서 호출되었는지 확인할 수 있습니다. 이벤트가 선택되었을 때만 정보를 표시하려면 ‘ View Event Information on Mouseover ’(4)를 비활성화하세요.
개요(10)는 데이터가 수집된 기간을 요약하여 보여줍니다. 확대/축소 범위(8)를 드래그하거나 개요를 클릭하여 개요를 이동할 수 있습니다. 또한 ‘ Jump to Previous Event ’ 및 ‘ Jump to Next Event ’(1)을 선택하여 이벤트 간을 이동할 수도 있습니다.
Show Zoom Slider (2)를 선택하면 확대/축소 수준을 설정하는 슬라이더가 열립니다. 확대/축소 핸들(9)을 드래그할 수도 있습니다. 기본 확대/축소 수준으로 재설정하려면 타임라인을 마우스 오른쪽 버튼으로 클릭하여 컨텍스트 메뉴를 열고, Reset Zoom 를 선택하십시오.
시간 눈금자를 선택하면 타임라인에 수직 방향선(5)이 추가됩니다.
이벤트 범위 선택
이벤트 범위(7)를 선택하면 이벤트의 프레임 속도를 확인하고 유사한 이벤트의 프레임 속도와 비교할 수 있습니다. Select Range (3)를 선택하여 선택 도구를 활성화합니다. 그런 다음 타임라인을 클릭하여 이벤트 범위의 시작점을 지정합니다. 선택 핸들을 드래그하여 범위의 끝점을 정의합니다. 범위의 길이는 이벤트의 프레임 속도를 나타냅니다.
연속된 두 이벤트 간의 지연 시간을 측정하려면 첫 번째 이벤트의 끝과 두 번째 이벤트의 시작 사이에 이벤트 범위를 설정하십시오. ‘ Duration ’ 필드에는 이벤트 간의 지연 시간이 밀리초 단위로 표시됩니다.
이벤트 범위를 확대하려면 해당 범위를 두 번 클릭하십시오.
Timeline, Statistics 및 Flame Graph 보기에서 현재 범위를 좁히려면, 해당 범위를 마우스 오른쪽 버튼으로 클릭하고 ‘ Analyze Current Range ’를 선택하십시오. 전체 범위로 돌아가려면 컨텍스트 메뉴에서 ‘ Analyze Full Range ’를 선택하십시오.
이벤트 범위를 제거하려면 ‘ Selection ’ 대화 상자를 닫으십시오.
데이터 이해
일반적으로 타임라인 보기의 이벤트는 QML 또는 JavaScript 실행에 소요된 시간을 나타냅니다. 마우스를 이벤트 위로 이동하면 세부 정보를 확인할 수 있습니다. 대부분의 이벤트에는 소스 코드 내 위치, 지속 시간 및 소스 코드 자체의 관련 부분이 포함됩니다.
이벤트를 선택하면 코드 편집기에서 커서가 해당 이벤트와 관련된 코드 부분으로 이동합니다.
다음과 같은 유형의 이벤트가 타임라인 보기에 한 줄 또는 여러 줄로 표시됩니다.
| 이벤트 범주 | 설명 |
|---|---|
| Pixmap Cache | 캐시된 픽스맵 데이터의 총량을 픽셀 단위로 표시합니다. 또한, 로드 중인 각 그림에 대해 별도의 이벤트를 표시하며, 해당 파일 이름 및 크기에 대한 세부 정보를 제공합니다. |
| Scene Graph | 씬 그래프 프레임이 렌더링된 시간과 이를 수행하는 데 실행된 다양한 단계에 대한 추가 타이밍 정보를 표시합니다. |
| Memory Usage | JavaScript 메모리 관리자의 블록 할당을 표시합니다. 일반적으로 메모리 관리자는 더 큰 메모리 블록을 한 번에 예약한 다음, 나중에 더 작은 단위로 애플리케이션에 할당합니다. 애플리케이션이 특정 크기를 초과하는 단일 메모리 블록을 요청하는 경우, 메모리 관리자는 이를 별도로 할당합니다. 이 두 가지 작동 모드는 서로 다른 색상의 이벤트로 표시됩니다. 두 번째 행에는 할당된 메모리의 실제 사용량이 표시됩니다. 이는 애플리케이션이 실제로 요청한 자바스크립트 힙의 양입니다. |
| Input Events | 마우스 및 키보드 이벤트를 표시합니다. |
| Painting | 사용되지 않습니다. |
| Animations | 활성화된 애니메이션의 수와 해당 애니메이션이 실행되는 프레임 속도를 표시합니다. 렌더 스레드 애니메이션은 별도의 행에 표시됩니다. |
| Compiling | QML 파일 컴파일에 소요된 시간을 표시합니다. |
| Creating | 씬 내 요소를 생성하는 데 소요된 시간을 표시합니다. 요소 생성은 두 단계로 진행됩니다. 첫 번째 단계는 자식 요소를 포함한 데이터 구조를 생성하는 단계입니다. 두 번째 단계는 완료 콜백을 처리하는 단계입니다. 다만 모든 요소가 완료 콜백을 트리거하는 것은 아닙니다. 각 단계는 타임라인에서 별도의 이벤트로 표시됩니다. |
| Binding | 바인딩이 평가되는 시점과 평가에 소요된 시간을 표시합니다. |
| Handling Signal | 신호가 처리되는 시점과 처리 소요 시간을 표시합니다. |
| JavaScript | 바인딩 및 신호 핸들러 뒤에 있는 실제 자바스크립트 실행에 소요된 시간을 표시합니다. 여기에는 바인딩을 평가하거나 신호를 처리하는 데 사용될 수 있는 모든 자바스크립트 함수가 나열됩니다. |
| Quick3D | Qt Quick 3D 프레임 렌더링에 소요된 시간, 프레임 준비 및 동기화에 대한 타이밍 정보, 파티클 시스템 업데이트 시간 및 파티클 업데이트 횟수, 텍스처 및 메쉬 메모리 할당량과 메모리 소비량을 표시합니다. 이 이벤트 유형은 Qt 6.3부터 사용할 수 있습니다. |
씬 그래프 이벤트 분석
씬 그래프 범주를 이해하려면 Qt Quick Scene Graph 및 Qt Quick Scene Graph Default Renderer에서 Qt Quick 씬 그래프의 작동 방식에 대해 자세히 읽어보십시오. 다음 이벤트들은 Scene Graph 범주에서 보고됩니다. 모든 이벤트가 모든 렌더 루프에서 생성되는 것은 아닙니다. Windows 및 Basic 렌더 루프에서는 모든 작업이 동일한 스레드에서 실행되므로 GUI 스레드와 렌더 스레드 간의 구분은 의미가 없습니다.
환경 변수 QSG_RENDER_TIMING을 설정하면, 프로파일링 대상 애플리케이션과 유사하지만 약간 다른 타이밍 정보를 텍스트로 출력할 수 있습니다. 차이점은 아래에 나열되어 있습니다.
| 이벤트 유형 | 스레드 | 렌더 루프 유형 | QSG_RENDER_TIMING 출력 시 표시되는 레이블 | 설명 |
|---|---|---|---|---|
| Polish | GUI | 스레드형, 기본형, Windows | polish | QQuickItem::updatePolish()를 사용하여 항목을 렌더링하기 전의 최종 마무리 작업. |
| GUI Thread Wait | GUI | 스레드 기반 | lock | QQuickWindow::afterAnimating() 신호에 연결된 슬롯을 실행한 다음, GUI Thread Sync 에서 동일한 뮤텍스를 대기하기 전에 렌더링 스레드의 뮤텍스를 잠급니다. 이 작업이 Render Thread Sync 보다 훨씬 일찍 시작되면, GUI 스레드에 여유 시간이 생겨 추가적인 QML 또는 JavaScript를 실행하는 데 사용할 수 있습니다. |
| GUI Thread Sync | GUI | 스레드 방식 | blockedForSync | GUI 스레드가 렌더링 스레드를 기다리며 차단되어 있는 시간입니다. |
| Animations | GUI | 스레드 방식, Windows | animations | GUI 스레드에서 애니메이션을 진행합니다. 기본 렌더 루프는 렌더링과 동기화되어 애니메이션을 구동하지 않습니다. 이것이 바로 기본 렌더 루프를 사용할 때 애니메이션 이벤트가 표시되지 않는 이유입니다. 이 경우의 애니메이션 타이밍을 확인하려면 Animations 카테고리를 참조하십시오. |
| Render Thread Sync | 렌더 | 스레드 방식, 기본, Windows | Frame rendered ... sync | QQuickItem::updatePaintNode()를 사용하여 QML 상태를 씬 그래프와 동기화합니다. |
| Render | 렌더 | 스레드형, 기본, Windows | Frame rendered ... render | 프레임 렌더링에 소요된 총 시간으로, 필요한 모든 데이터를 준비하고 GPU로 업로드하는 시간이 포함됩니다. 이는 총 렌더링 시간입니다. 아래의 순 Render Render 시간과 혼동하지 마십시오. |
| Swap | 렌더링 | 스레드 방식, 기본, Windows | Frame rendered ... swap | 렌더링 후 프레임 교체. |
| Render Preprocess | 렌더링 | 스레드 방식, 기본, Windows | time in renderer ... preprocess | 전처리가 필요한 모든 노드에서 ` QSGNode::preprocess()`를 호출합니다. 이는 ' Render ' 단계의 일부입니다. |
| Render Update | 렌더링 | 스레드 방식, 기본, Windows | time in renderer ... updates | 씬 그래프의 모든 노드를 반복 처리하여 지오메트리, 변환, 불투명도 및 기타 상태를 업데이트합니다. ` Render Thread Sync ` 단계에서는 각 노드가 GUI 스레드의 상태를 받아 개별적으로 업데이트됩니다. ` Render Update` 단계에서는 모든 노드가 결합되어 최종 씬이 생성됩니다. 이는 ` Render ` 단계의 일부입니다. |
| Render Bind | 렌더링 | 스레드 기반, 기본, Windows | time in renderer ... binding | OpenGL 렌더링을 위해 올바른 프레임버퍼를 바인딩합니다. 이는 Render 단계의 일부입니다. |
| Render Render | 렌더링 | 스레드 방식, 기본, Windows | time in renderer ... rendering | OpenGL을 통해 모든 데이터를 GPU로 전송하는 실제 과정입니다. 이는 ' Render ' 단계의 일부입니다. |
| Material Compile | 렌더링 | 스레드 방식, 기본, Windows | shader compiled | GLSL 셰이더 프로그램 컴파일. |
| Glyph Render | 렌더링 | 스레드 기반, 기본, Windows | glyphs ... rendering | 글꼴 글리프를 텍스처로 렌더링합니다. |
| Glyph Upload | 렌더링 | 스레드 방식, 기본, Windows | glyphs ... upload | 글리프 텍스처를 GPU로 업로드합니다. |
| Texture Bind | 렌더링 | 스레드 방식, 기본, Windows | plain texture ... bind | glBindTextures를 사용하여 OpenGL 컨텍스트에 텍스처를 바인딩합니다. |
| Texture Convert | 렌더링 | 스레드 방식, 기본, Windows | plain texture ... convert | 텍스처로 사용하기에 적합하도록 이미지의 형식을 변환하고 크기를 축소합니다. |
| Texture Swizzle | 렌더링 | 스레드, 기본, Windows | plain texture ... swizzle | 필요한 경우 CPU에서 텍스처 데이터를 스위즐링합니다. |
| Texture Upload | 렌더링 | 스레드 기반, 기본, Windows | plain texture ... upload / atlastexture uploaded | 텍스처 데이터를 GPU로 업로드합니다. |
| Texture Mipmap | 렌더링 | 스레드 방식, 기본, Windows | plain texture ... mipmap | GPU에서 텍스처에 미프매핑을 적용합니다. |
| Texture Delete | 렌더링 | 스레드 방식, 기본, Windows | plain texture deleted | 더 이상 필요하지 않은 텍스처를 GPU에서 삭제합니다. |
Qt Quick 3D 이벤트 분석
다음은 ` Qt Quick 3D`에 대한 이벤트 목록입니다. 렌더링된 각 프레임은 동기화, 준비 및 렌더링 단계로 구성되며, 이 단계들은 해당 순서대로 수행됩니다. 동기화는 씬 그래프 동기화 단계에서 발생하며, 준비 및 렌더링은 씬 그래프 렌더링 단계에서 발생합니다.
환경 변수 ` QSG_RENDERER_DEBUG=render `을 설정하면 다양한 렌더링 패스의 렌더 호출 횟수에 대한 추가 텍스트 출력을 확인할 수 있습니다. 이러한 호출 횟수는 `Render Frame` 이벤트에서 합산됩니다.
| 이벤트 유형 | 스레드 | 설명 |
|---|---|---|
| Render Frame | 렌더 | 프레임의 렌더링 시간입니다. 또한 드로우 호출 횟수도 표시합니다. |
| Prepare Frame | 렌더 | 프레임을 준비하는 데 걸리는 시간입니다. 리소스는 준비 단계에서 할당 및 로드됩니다. 씬 로딩 후 첫 번째 프레임은 대부분의 리소스가 이때 로드되기 때문에 일반적으로 다른 프레임보다 시간이 더 오래 걸립니다. |
| Synchronize Frame | 렌더 | 프레임의 동기화 시간입니다. 동기화 단계에서는 프론트엔드에서 백엔드 값을 업데이트합니다. 또한 Qt Quick Scene Graph와 Qt Quick 3D 간의 공유 리소스를 관리합니다. |
| Mesh Load | 렌더 | 메시의 로딩 시간입니다. 모든 메시의 총 메모리 사용량을 표시합니다. 언로드된 메시도 표시합니다. |
| Custom Mesh Load | 렌더 | 커스텀 메시의 로드 시간. 모든 메시의 총 메모리 사용량을 표시합니다. 또한 언로드된 메시도 표시합니다. |
| Texture Load | 렌더 | 텍스처의 로드 시간. 모든 텍스처의 총 메모리 사용량을 표시합니다. 언로드된 텍스처도 표시합니다. |
| Generate Shader | 렌더 | 머티리얼용 셰이더를 생성하는 데 걸리는 시간입니다. |
| Load Shader | 렌더 | 내장 셰이더를 불러오는 데 걸리는 시간. |
| Particle Update | GUI | 파티클 시스템의 업데이트 시간입니다. 업데이트된 파티클의 수를 표시합니다. |
| Mesh Memory Consumption | 렌더링 | 전체 메쉬 메모리 사용량을 막대 그래프로 표시합니다. |
| Texture Memory Consumption | 렌더 | 전체 텍스처 메모리 사용량을 막대 그래프로 표시합니다. |
| Render Call | 렌더링 | 단일 드로우 또는 컴퓨트 호출에 소요된 시간입니다. GPU 부하가 큰 작업을 파악하는 데 유용합니다. |
| Render Pass | 렌더링 | 전체 렌더링 패스에 소요된 시간입니다. 프레임 버퍼에 대한 렌더링 작업을 그룹화하여 표시합니다. |
통계 보기
Statistics (바인딩, 생성, 컴파일, JavaScript, 신호) 뷰는 각 바인딩, 생성, 컴파일, JavaScript 또는 신호 이벤트가 트리거된 횟수와 소요된 평균 시간을 표시합니다. 통계를 검토하여 최적화해야 할 이벤트를 파악하십시오. 발생 횟수가 많다면 해당 이벤트가 불필요하게 트리거되고 있음을 나타낼 수 있습니다. 발생 건수에 대한 중앙값, 최장 시간 및 최단 시간을 보려면 컨텍스트 메뉴에서 ‘ Extended Event Statistics ’를 선택하십시오.
이벤트를 선택하면 코드 편집기의 소스 코드에서 해당 이벤트 위치로 이동합니다.

Callers ' Callees '는 이벤트 간의 종속성을 보여줍니다. 이를 통해 애플리케이션의 내부 기능을 분석할 수 있습니다. ' Callers '는 바인딩을 트리거하는 QML 이벤트를 요약합니다. 이를 통해 바인딩의 변경 원인을 파악할 수 있습니다. ' Callees '는 바인딩이 트리거하는 QML 이벤트를 요약합니다. 이를 통해 바인딩을 변경할 경우 어떤 QML 이벤트가 영향을 받는지 알 수 있습니다.
이벤트를 선택하면 코드 편집기의 소스 코드에서 해당 위치로 이동합니다.
Timeline 뷰에서 이벤트를 선택하면, 해당 이벤트에 대한 정보가 Statistics 및 Flame Graph 뷰에 표시됩니다.
한 뷰나 행의 내용을 클립보드에 복사하려면 컨텍스트 메뉴에서 ‘ Copy Table ’ 또는 ‘ Copy Row ’을 선택하십시오.
플레임 그래프로 통계 시각화
Flame Graph 뷰는 QML 및 JavaScript 실행에 대한 보다 간결한 통계 개요를 보여줍니다. Total Time 뷰에서 수평 막대는 모든 JavaScript 및 QML 이벤트의 총 실행 시간에 비해 특정 함수의 모든 호출이 합산하여 소요된 시간을 나타냅니다. 중첩 구조는 어떤 함수가 다른 어떤 함수에 의해 호출되었는지를 보여줍니다.

함수별로 할당된 총 메모리 양을 확인하려면 드롭다운 메뉴에서 ‘ Memory ’를 선택하십시오.
함수별로 수행된 메모리 할당 횟수를 보려면 ‘ Allocations ’를 선택하십시오.
뷰에서 항목을 두 번 클릭하면 해당 항목을 확대할 수 있습니다. 뷰의 빈 영역을 두 번 클릭하면 다시 축소됩니다.
Timeline 뷰와 달리, Flame Graph 뷰는 QML이나 JavaScript가 전혀 실행되지 않는 시간 범위는 표시하지 않습니다. 따라서 프레임별 실행 시간을 분석하는 데는 적합하지 않습니다. 하지만 다양한 QML 및 JavaScript 이벤트가 미치는 전체적인 영향을 확인하기에는 매우 유용합니다.
‘방법: 분석’, ‘분석기’, ‘코드 분석’ 및 ‘QML 애플리케이션 프로파일링’항목도 참조하십시오 .
Copyright © The Qt Company Ltd. and other contributors. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.