측정항목은 벤치마크에서 추출된 기본 정보 유형입니다. `measureRepeated` 함수에 `List`로 전달되므로 측정된 여러 측정항목을 한 번에 지정할 수 있습니다. 벤치마크를 실행하려면 측정항목 유형이 하나 이상 필요합니다.
다음 코드 스니펫은 Jetpack Compose 지연 레이아웃 인터페이스의 프레임 타이밍 및 맞춤 트레이스 섹션 측정항목을 캡처합니다.
@OptIn(ExperimentalMetricApi::class)
@Test
fun scrollComposeList() {
benchmarkRule.measureRepeated(
// [START_EXCLUDE]
packageName = TARGET_PACKAGE,
metrics = listOf(
FrameTimingMetric(),
// Measure power usage. This is supported on Pixel 6 and later.
PowerMetric(PowerMetric.Type.Power(
mapOf(
PowerCategory.CPU to PowerCategoryDisplayLevel.TOTAL,
PowerCategory.DISPLAY to PowerCategoryDisplayLevel.TOTAL,
PowerCategory.GPU to PowerCategoryDisplayLevel.TOTAL,
PowerCategory.NETWORK to PowerCategoryDisplayLevel.TOTAL,
)
)),
// Measure custom trace sections by name EntryRow (which is added to the EntryRow composable).
// Mode.Sum measures combined duration and also how many times it occurred in the trace.
// This way, you can estimate whether a composable recomposes more than it should.
TraceSectionMetric("EntryRowCustomTrace", TraceSectionMetric.Mode.Sum),
// This trace section takes into account the SQL wildcard character %,
// which can find trace sections without the full name.
// This way, you can measure composables produced by the composition tracing
// and measure how long they took and how many times they recomposed.
// WARNING: This metric only shows results when running with composition tracing, otherwise it won't be visible in the outputs.
TraceSectionMetric("%EntryRow%", TraceSectionMetric.Mode.Sum),
),
// Try switching to different compilation modes to see the effect
// it has on frame timing metrics.
compilationMode = CompilationMode.None(),
startupMode = StartupMode.WARM, // restarts activity each iteration
iterations = DEFAULT_ITERATIONS,
// [END_EXCLUDE]
setupBlock = {
uiAutomator {
// Before starting to measure, navigate to the UI to be measured.
startIntent(Intent("$packageName.COMPOSE_ACTIVITY"))
}
}
) {
uiAutomator {
onElement { isScrollable }.fling(Direction.DOWN)
}
}
}
다음 예에서 EntryRowCustomTrace는 표준 Kotlin trace(sectionName) { ... } 블록 래퍼를 사용하여 구성 가능한 항목 레이어 내에 정의된 맞춤 트레이스 섹션을 나타냅니다. TraceSectionMetric의 데이터를 제공하려면 애플리케이션의 프로덕션 코드베이스 내에서 표준 Jetpack 런타임 trace 블록 래퍼로 대상 UI 구성요소를 래핑해야 합니다.
@Composable
private fun EntryRow(entry: Entry, modifier: Modifier = Modifier) = trace("EntryRowCustomTrace") {
Card(modifier = modifier) {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
text = entry.contents,
modifier = Modifier
.padding(16.dp)
.wrapContentSize()
)
Spacer(modifier = Modifier.weight(1f))
Checkbox(
checked = false,
onCheckedChange = {},
modifier = Modifier.padding(16.dp)
)
}
}
}
벤치마크 결과는 그림 1과 같이 Android 스튜디오 내의 벤치마크 터미널 탭에 직접 출력됩니다. 측정항목을 여러 개 정의하면 계산된 모든 데이터 포인트가 요약 창에 결합됩니다.
TraceSectionMetric 및 FrameTimingMetric의 결합된 콘솔 결과StartupTimingMetric, FrameTimingMetric, TraceSectionMetric, PowerMetric은 아래에서 자세히 설명합니다. 사용 가능한
벤치마크 측정항목의 전체 목록은 API
참조의 Metric 하위 클래스를 참고하세요.
StartupTimingMetric
StartupTimingMetric 은 다음 값을 사용하여 앱 시작 시간 측정항목을 캡처합니다.
timeToInitialDisplayMs: 시스템이 시작 인텐트를 수신한 시점부터 대상 화면의 첫 번째 프레임을 렌더링하는 시점까지 걸린 시간입니다.timeToFullDisplayMs: 시스템이 시작 인텐트를 수신한 시점부터 앱이 내부 플랫폼 보고 메커니즘을 사용하여 완전히 그려진 시점까지 걸린 시간입니다. 완전히 그려진 신호 후(또는 해당 신호 포함) 첫 번째 프레임의 렌더링이 완료되면 측정이 중지됩니다.
StartupTimingMetric 은 시작 반복에서 최솟값, 중앙값, 최댓값을 출력합니다. 시작 개선을 평가하려면 항상 중앙값에 집중해야 합니다. 중앙값으로 일반적인 사용자 시작 시간을 가장 잘 추정할 수 있기 때문입니다.
Compose 우선 아키텍처에서는 activity.reportFullyDrawn을 수동으로 호출하지 마세요. 대신 화면 구성 가능 함수 내에서 Compose에 안전한 비동기 유틸리티 ReportDrawn, ReportDrawnWhen, 또는 ReportDrawnAfter를 사용하여 비동기 네트워크 데이터 또는 복잡한 UI 상태의 렌더링이 완료되면 Macrobenchmark에 자동으로 신호를 보냅니다.
초기화 성능 분석 및 최적화에 관한 자세한 내용은 앱 시작 시간을 참고하세요.
FrameTimingMetric
FrameTimingMetric 은 목록 스크롤 또는 복잡한 UI 레이아웃 애니메이션과 같은 벤치마크 여정에서 생성된 프레임의 정확한 타이밍 정보를 캡처하고 다음 진단 값을 출력합니다.
frameOverrunMs: 주어진 프레임이 기한을 넘긴 시간입니다. 양수는 눈에 보이는 버벅거림 또는 끊김 현상이 동반된 드롭된 프레임을 나타냅니다. 음수는 프레임이 하위 시스템 하드웨어 기한에 비해 얼마나 빨리 완료되었는지 나타냅니다. 참고: 이 측정항목은 Android 12 (API 수준 31) 이상에서만 사용할 수 있습니다.frameDurationCpuMs: 기본 애플리케이션 UI 스레드와 ComposeRenderThread모두에서 CPU에서 프레임이 활발하게 생성되는 데 걸린 시간입니다.
이러한 측정값은 50번째, 90번째, 95번째, 99번째 백분위수로 분포되어 수집됩니다.
frameDurationCpuMs P50 3.5, P90 6.0, P95 6.4, P99 11.0
frameOverrunMs P50 -11.6, P90 -7.2, P95 -7.1, P99 -1.2
Jetpack Compose 레이아웃 계층 구조를 최적화할 때는 성능이 가장 낮은 프레임 (P95 및 P99 경계)을 살펴보세요. 높은 백분위수에서 frameOverrunMs가 양의 정수로 급증하면 재구성으로 인해 스크롤 애니메이션이 많은 동안 기본 스레드가 정지되는 것입니다.
느린 프레임 식별 및 해결에 관한 자세한 내용은 Jetpack Compose 성능을 참고하세요.
TraceSectionMetric
TraceSectionMetric 은 특정 트레이스 섹션이 발생하는 횟수와 실행에 걸리는 절대 시간을 캡처합니다. 시간 추적의 경우 최소 시간, 중앙값, 최대 시간을 밀리초 단위로 출력합니다. 대상
트레이스 섹션은 함수 호출 trace(sectionName)
또는
Trace.beginSection(sectionName) 및 Trace.endSection() 또는 비동기 변형 간의 하위 수준 블록 경계로 정의됩니다.
EntryRowCustomTraceCount min 20.0, median 28.0, max 50.0
EntryRowCustomTraceSumMs min 34.9, median 44.4, max 66.6
기본적으로 측정항목은 자체 애플리케이션 패키지 바이너리에서 직접 컴파일된 트레이스 섹션만 출력합니다. 앱의 패키지 경계 외부에서 시작된 프로세스를 포함하려면 targetPackageOnly = false 속성을 설정하세요.
Jetpack Compose 런타임 트레이싱을 사용할 때는 컴포지션 트레이싱을 사용 설정하여 수동 트레이스 래퍼를 작성하지 않고도 시스템 트레이스 그래프에 개별 구성 가능 함수를 표시할 수 있습니다.
대상 애플리케이션에 androidx.compose.runtime:runtime-tracing 종속 항목을 추가하는 것만으로 수동 프로파일러 트레이스를 실행할 수 있지만 Macrobenchmark 실행 내에서 프로그래매틱 방식으로 이러한 트레이스를 캡처하려면 벤치마크 모듈 내에서 추가 구성이 필요합니다.
전체 설정 안내는 Jetpack Macrobenchmark로 트레이스 캡처를 참고하세요.
PowerMetric
PowerMetric 은 Macrobenchmark 실행 기간 동안 전력 또는 에너지의 변화를 캡처합니다. 선택된 각 카테고리는 측정 가능한 하드웨어 구성요소로 분류되는 반면 선택되지 않은 카테고리는 '선택 해제됨' 버킷으로 그룹화됩니다.
하드웨어 요구사항: 이러한 측정항목은 앱별 계산이 아닌 시스템 전체 소비를 측정합니다. 따라서 데이터 수집은 실제 Google Pixel 6, Pixel 6 Pro 및 이후 버전의 실제 기기로 제한됩니다.
측정항목은 카테고리당 두 가지 측정값을 출력합니다.
power<category>Uw: 이 카테고리에서 테스트 기간 동안 소모된 전력량입니다 (마이크로와트 단위로 측정).energy<category>Uws: 이 카테고리에서 테스트 기간 동안 시간 단위당 전송된 총 에너지의 양입니다 (마이크로와트초 단위로 측정).
카테고리에는 다음이 포함됩니다.
CPUDISPLAYGPUGPSMEMORYMACHINE_LEARNINGNETWORKUNCATEGORIZED
CPU와 같은 일부 카테고리에서는 다른 프로세스에서 실행한 작업과 자체 앱에서 실행한 작업을 구분하기 어려울 수 있습니다. 간섭을 최소화하려면 불필요한 앱과 계정을 삭제하거나 제한하세요.
powerCategoryCpuUw min 300.2, median 346.1, max 519.6
powerCategoryDisplayUw min 319.8, median 325.8, max 329.7
powerCategoryGpuUw min 18.8, median 23.3, max 36.9
powerCategoryNetworkUw min 97.3, median 123.3, max 681.3
powerTotalUw min 1234.8, median 1316.6, max 2112.4
powerUnselectedUw min 483.3, median 512.6, max 561.7
핵심 하위 시스템 분석
PowerMetric 은 제공된 전원 카테고리에 대해 테스트 기간 동안 전력 또는 에너지의 변화를 캡처합니다. 선택된 각 카테고리는 측정 가능한 하위 구성요소로 분류되는 반면 선택되지 않은 카테고리는 '선택 해제됨' 측정항목에 추가됩니다.
터미널 출력은 요청한 구성에 매핑됩니다.
powerCategoryCpuUw: 테스트 기간 동안 CPU에서 소모된 전력량입니다.powerCategoryGpuUw: 테스트 기간 동안 GPU에서 소모된 전력량입니다.powerUnselectedUw: 초기화 맵에서 명시적으로 요청되지 않은 사용 가능한 모든 하드웨어 카테고리에서 소모된 총 전력입니다.
실행 중에 하드웨어 레일에서 불규칙한 데이터 급증을 방지하려면 화면 밝기를 고정 값으로 잠그고, 안정적인 기기 온도를 유지하며, Macrobenchmark 루프를 시작하기 전에 경쟁 백그라운드 프로세스를 닫으세요.
추가 리소스
콘텐츠 보기
추천 서비스
- 참고: JavaScript가 사용 중지되어 있으면 링크 텍스트가 표시됩니다.
- 기준 프로필 만들기{:#creating-profile-rules}
- Macrobenchmark 작성
- 앱 시작 분석 및 최적화{:#app-startup-analysis-optimization}