QML 애플리케이션 프로파일링
QML Profiler 을 사용하면 애플리케이션의 속도 저하, 응답이 없고 끊기는 사용자 인터페이스와 같은 일반적인 성능 문제의 원인을 찾을 수 있습니다. 일반적인 원인으로는 너무 적은 프레임에 너무 많은 자바스크립트가 실행되는 경우가 있습니다. GUI 스레드가 진행되기 전에 모든 자바스크립트가 반환되어야 하며, GUI 스레드가 준비되지 않은 경우 프레임이 지연되거나 중단됩니다.
유사한 성능 문제의 또 다른 일반적인 원인은 보이지 않는 항목을 만들거나 업데이트하는 경우이며, 이 경우 GUI 스레드에서 시간이 걸립니다.
페인트 메서드 및 신호 처리기와 같이 오래 실행되는 C++ 함수를 트리거하는 것도 GUI 스레드에서 시간이 걸리지만, C++ 코드를 프로파일링하지 않기 때문에 QML Profiler 에서 보기가 더 어렵습니다. 과도한 JavaScript 사용을 찾으려면 애니메이션과 씬 그래프 이벤트의 프레임 속도를 확인하고, 간격을 찾아 애플리케이션이 예상대로 작동하는지 확인하세요. JavaScript 카테고리에는 함수의 실행 시간이 표시되며, 프레임당 16ms 미만으로 유지하도록 노력해야 합니다.
보이지 않는 항목 처리로 인한 문제를 찾으려면 드롭된 프레임을 찾고 프레임당 업데이트되는 짧은 바인딩이나 신호 처리기를 너무 많이 사용하고 있지 않은지 확인하세요. 씬 그래프 오버드로를 시각화하여 씬 레이아웃을 확인하고 화면 외부에 위치하거나 다른 보이는 요소 아래에 숨겨져 있어 사용자에게 보이지 않는 항목을 찾을 수도 있습니다.
자바스크립트가 실행되고 있지 않은데도 프레임이 끊기고 타임라인에 설명할 수 없는 큰 간격이 있는 경우 사용자 지정 QQuickItem 구현을 확인하세요. Valgrind Callgrind 또는 기타 범용 프로파일러를 사용하여 C++ 코드를 분석할 수 있습니다.
풀 스택 추적을 사용해 최상위 레벨의 QML 또는 JavaScript에서 C++, 그리고 커널 공간까지 추적할 수 있습니다. 수집된 데이터는 Chrome 추적 형식 뷰어에서 확인할 수 있습니다.
수집된 데이터 분석하기
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 | 자바스크립트 메모리 관리자의 블록 할당을 표시합니다. 일반적으로 메모리 관리자는 큰 메모리 블록을 한 번에 예약한 다음 나중에 애플리케이션에 작은 비트 단위로 나눠서 제공합니다. 애플리케이션이 특정 크기를 초과하는 단일 메모리 블록을 요청하면 메모리 관리자는 이를 개별적으로 할당합니다. 이 두 가지 작동 모드는 서로 다른 색상의 이벤트로 표시됩니다. 두 번째 행은 할당된 메모리의 실제 사용량을 표시합니다. 애플리케이션이 실제로 요청한 자바스크립트 힙의 양입니다. |
| Input Events | 마우스 및 키보드 이벤트를 표시합니다. |
| Painting | 사용되지 않음. |
| Animations | 활성화된 애니메이션의 양과 실행 중인 프레임 속도를 표시합니다. 렌더 스레드 애니메이션은 별도의 행에 표시됩니다. |
| Compiling | QML 파일 컴파일에 소요된 시간을 표시합니다. |
| Creating | 씬에서 요소를 만드는 데 소요된 시간을 표시합니다. 요소 생성은 두 단계로 진행됩니다. 첫 번째 단계는 자식 요소를 포함한 데이터 구조를 생성하는 단계입니다. 두 번째 단계는 완료 콜백을 나타냅니다. 하지만 모든 요소가 완료 콜백을 트리거하는 것은 아닙니다. 각 단계는 타임라인에서 별도의 이벤트로 표시됩니다. |
| Binding | 바인딩이 평가되는 시간과 평가에 걸리는 시간을 표시합니다. |
| Handling Signal | 신호가 처리된 시간과 처리 시간을 표시합니다. |
| JavaScript | 바인딩 및 신호 처리기 뒤에 있는 실제 자바스크립트를 실행하는 데 소요된 시간을 표시합니다. 바인딩을 평가하거나 신호를 처리하는 데 사용할 수 있는 모든 JavaScript 함수가 나열됩니다. |
| Quick3D | Qt Quick 3D 프레임 렌더링에 소요된 시간, 프레임 준비 및 동기화를 위한 타이밍 정보, 파티클 시스템 업데이트 시간 및 파티클 업데이트 횟수, 텍스처 및 메시 메모리 할당 및 메모리 소비량을 표시합니다. 이 이벤트 유형은 Qt 6.3부터 사용할 수 있습니다. |
씬 그래프 이벤트 분석하기
씬 그래프 카테고리를 이해하려면 Qt Quick 씬 그래프 및 Qt Quick 씬 그래프 기본 렌더러에서 Qt Quick 씬 그래프 작동 방식에 대해 자세히 읽어보십시오. 다음 이벤트는 Scene Graph 카테고리에서 보고됩니다. 모든 이벤트가 모든 렌더 루프에서 생성되는 것은 아닙니다. Windows 및 기본 렌더 루프에서는 모든 것이 동일한 스레드에서 실행되며 GUI 스레드와 렌더 스레드의 구분은 무의미합니다.
프로파일링 중인 애플리케이션과 비슷하지만 약간 다른 타이밍의 텍스트 출력을 얻으려면 환경 변수 QSG_RENDER_TIMING을 설정하세요. 차이점은 다음과 같습니다.
| 이벤트 유형 | 스레드 | 렌더링 루프 유형 | QSG_RENDER_TIMING 출력의 레이블 | 설명 |
|---|---|---|---|---|
| Polish | GUI | 스레드, 기본, 윈도우 | polish | QQuickItem::updatePolish()를 사용하여 렌더링하기 전에 항목을 최종적으로 수정합니다. |
| GUI Thread Wait | GUI | Threaded | lock | QQuickWindow::afterAnimating() 신호에 연결된 슬롯을 실행한 다음 GUI Thread Sync 에서 동일한 뮤텍스에서 대기하기 전에 렌더링 스레드의 뮤텍스를 잠급니다. 이 작업이 Render Thread Sync 보다 훨씬 전에 시작되면 추가 QML 또는 JavaScript를 실행하는 데 사용할 수 있는 여유 시간이 GUI 스레드에 있습니다. |
| GUI Thread Sync | GUI | Threaded | blockedForSync | 렌더링 스레드를 기다리며 GUI 스레드가 차단된 시간입니다. |
| Animations | GUI | 스레드, 윈도우 | animations | GUI 스레드에서 애니메이션을 진행합니다. 기본 렌더 루프는 렌더링과 동기화하여 애니메이션을 구동하지 않습니다. 그렇기 때문에 기본 렌더 루프를 사용할 때 애니메이션 이벤트가 표시되지 않습니다. 이 경우 애니메이션 타이밍을 보려면 Animations 카테고리를 참조하세요. |
| Render Thread Sync | 렌더링 | 스레드, 기본, 윈도우 | Frame rendered ... sync | QQuickItem::updatePaintNode()를 사용하여 QML 상태를 씬 그래프에 동기화합니다. |
| Render | Render | 스레드, 기본, 윈도우 | Frame rendered ... render | 필요한 모든 데이터를 준비하고 GPU에 업로드하는 것을 포함하여 프레임을 렌더링하는 데 소요된 총 시간입니다. 총 렌더링 시간입니다. 아래의 순 Render Render 시간과 혼동하지 마세요. |
| Swap | 렌더링 | 스레드, 기본, 윈도우 | Frame rendered ... swap | 렌더링 후 프레임 교체. |
| Render Preprocess | 렌더링 | 스레드, 기본, 윈도우 | time in renderer ... preprocess | 전처리가 필요한 모든 노드에서 QSGNode::preprocess()를 호출합니다. 이것은 총 Render 단계의 일부입니다. |
| Render Update | 렌더링 | 스레드, 기본, 윈도우 | time in renderer ... updates | 씬 그래프의 모든 노드를 반복하고 처리하여 지오메트리, 변환, 불투명도 및 기타 상태를 업데이트합니다. Render Thread Sync 단계에서는 각 노드가 GUI 스레드의 상태로 개별적으로 업데이트됩니다. Render Update 에서는 모든 노드가 결합되어 최종 장면이 생성됩니다. 이는 총 Render 단계의 일부입니다. |
| Render Bind | 렌더링 | 스레드, 기본, 윈도우 | time in renderer ... binding | OpenGL 렌더링을 위한 올바른 프레임버퍼를 바인딩합니다. 이는 총 Render 단계의 일부입니다. |
| Render Render | Render | 스레드, 기본, 윈도우 | time in renderer ... rendering | OpenGL을 통해 모든 데이터를 GPU로 전송하는 실제 프로세스입니다. 전체 Render 단계의 일부입니다. |
| Material Compile | Render | 스레드, 기본, 윈도우 | shader compiled | GLSL 셰이더 프로그램 컴파일. |
| Glyph Render | Render | 스레드, 기본, Windows | glyphs ... rendering | 글꼴 글리프를 텍스처로 렌더링합니다. |
| Glyph Upload | 렌더 | 스레드, 기본, Windows | glyphs ... upload | 글리프 텍스처를 GPU에 업로드합니다. |
| Texture Bind | 렌더 | 스레드, 기본, 윈도우 | plain texture ... bind | glBindTextures를 사용하여 OpenGL 컨텍스트에서 텍스처를 바인딩합니다. |
| Texture Convert | 렌더 | 스레드, 기본, 윈도우 | plain texture ... convert | 이미지를 텍스처로 사용하기에 적합하도록 포맷을 변환하고 이미지를 다운스케일링합니다. |
| Texture Swizzle | 렌더 | 스레드, 기본, 윈도우 | plain texture ... swizzle | 필요한 경우 텍스처 데이터를 CPU에서 스위즐링합니다. |
| Texture Upload | 렌더 | 스레드, 기본, 윈도우 | plain texture ... upload / atlastexture uploaded | 텍스처 데이터를 GPU에 업로드합니다. |
| Texture Mipmap | 렌더 | 스레드, 기본, 윈도우 | plain texture ... mipmap | GPU에서 텍스처를 밉매핑합니다. |
| Texture Delete | 렌더 | 스레드, 기본, 윈도우 | plain texture deleted | 불필요해진 텍스처를 GPU에서 삭제합니다. |
Qt Quick 3D 이벤트 분석
다음은 Qt Quick 3D의 이벤트 목록입니다. 렌더링되는 각 프레임은 동기화, 준비 및 렌더링 단계로 구성되며, 이 단계는 순서대로 수행됩니다. 동기화는 씬 그래프 동기화 단계에서 발생하고, 준비 및 렌더링은 씬 그래프 렌더링 단계에서 발생합니다.
환경 변수 QSG_RENDERER_DEBUG=render 를 설정하면 다양한 렌더링 패스의 렌더링 호출 횟수를 추가로 텍스트로 출력할 수 있습니다. 이러한 호출 횟수는 렌더 프레임 이벤트에 합산됩니다.
| 이벤트 유형 | Thread | 설명 |
|---|---|---|
| Render Frame | Render | 프레임의 렌더링 시간입니다. 드로우 호출 횟수도 표시됩니다. |
| Prepare Frame | 렌더링 | 프레임을 준비하는 데 걸린 시간입니다. 리소스는 준비 단계에서 할당되고 로드됩니다. 씬 로딩 후 첫 번째 프레임은 대부분의 리소스가 이때 로드되므로 일반적으로 다른 프레임보다 오래 걸립니다. |
| Synchronize Frame | 렌더링 | 프레임의 시간을 동기화합니다. 동기화는 프론트엔드에서 백엔드 값을 업데이트하는 작업을 처리합니다. 또한 Qt Quick 씬 그래프와 Qt Quick 3D 간의 공유 리소스도 관리합니다. |
| Mesh Load | 렌더 | 메시의 로드 시간입니다. 모든 메시의 총 메모리 사용량을 표시합니다. 언로드도 표시합니다. |
| Custom Mesh Load | 렌더 | 커스텀 메시의 로드 시간입니다. 모든 메시의 총 메모리 사용량을 표시합니다. 언로드도 표시됩니다. |
| Texture Load | 렌더 | 텍스처의 로드 시간입니다. 모든 텍스처의 총 메모리 사용량을 표시합니다. 언로드도 표시합니다. |
| Generate Shader | 렌더 | 머티리얼의 셰이더를 생성하는 데 걸린 시간입니다. |
| Load Shader | 렌더 | 빌트인 셰이더를 로드하는 데 걸린 시간입니다. |
| Particle Update | GUI | 파티클 시스템의 업데이트 시간입니다. 업데이트된 파티클 수를 표시합니다. |
| Mesh Memory Consumption | 렌더 | 총 메시 메모리 사용량을 막대 뷰로 표시합니다. |
| Texture Memory Consumption | Render | 총 텍스처 메모리 사용량을 막대 뷰로 표시합니다. |
| Render Call | 렌더 | 단일 그리기 또는 계산 호출에 걸린 시간입니다. GPU 작업량이 많은 작업을 식별하는 데 유용합니다. |
| Render Pass | 렌더 | 전체 렌더 패스에 걸린 시간입니다. 프레임 버퍼에 대한 그룹화된 렌더링 작업을 표시합니다. |
통계 보기
Statistics 보기에는 각 바인딩, 생성, 컴파일, 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.