컴포지션 추적

추적은 성능 문제를 처음 살펴볼 때 가장 좋은 정보 출처입니다. 이를 바탕으로 문제가 무엇이고 어디서부터 살펴보아야 하는지에 관한 가설을 세울 수 있습니다.

Android에서는 시스템 추적과 메서드 트레이스, 이렇게 두 가지 수준의 추적이 지원됩니다.

시스템 추적은 추적하도록 표시된 영역만 추적하므로 오버헤드가 낮고 앱의 성능에 크게 영향을 미치지 않습니다. 시스템 추적은 코드의 특정 섹션을 실행하는 데 걸리는 시간을 파악하는 데 좋습니다.

메서드 트레이스는 앱의 모든 함수 호출을 추적합니다. 이 방법은 비용이 많이 들기 때문에 앱의 성능에 크게 영향을 미치지만, 무슨 일이 일어나고 있는지, 어떤 함수가 얼마나 자주 호출되고 있는지를 전체적으로 파악할 수 있습니다.

시스템 추적에는 기본적으로 개별 구성 가능한 함수가 포함되지 않습니다. 개별 구성 가능한 함수는 메서드 트레이스에서 사용할 수 있습니다.

Google에서는 현재 시스템 추적 내에서 구성 가능한 함수를 표시할 수 있도록 새로운 시스템 추적 기능을 테스트하고 있습니다. 이 기능은 시스템 추적의 낮은 오버헤드와 메서드 트레이스 수준의 컴포지션 세부 정보라는 두 가지 이점을 제공합니다.

컴포지션 추적 설정

프로젝트에서 재구성 추적을 사용해 보려면 최소한 다음 버전으로 업데이트해야 합니다.

  • Android 스튜디오 Flamingo
  • Compose UI: 1.3.0
  • Compose Compiler: 1.3.0

추적을 실행하는 기기 또는 에뮬레이터도 API 수준 30 및 이후 버전이어야 합니다.

또한 Compose 런타임 추적에 새 종속 항목을 추가해야 합니다.

implementation("androidx.compose.runtime:runtime-tracing:1.0.0-beta01")

이 종속 항목을 추가하고 재구성이 포함된 시스템 추적을 실행하면 구성 가능한 함수를 자동으로 볼 수 있습니다.

시스템 추적 실행

시스템 추적을 실행하여 새로운 재구성 추적이 어떻게 작동하는지 확인하려면 다음 단계를 따르세요.

  1. 프로파일러를 엽니다.

    Android 스튜디오 - 프로파일링 시작
    그림 2. Android 스튜디오 - 프로파일링 시작
  2. CPU 타임라인을 클릭합니다.

    Android 스튜디오 프로파일러 - CPU 타임라인
    그림 3. Android 스튜디오 프로파일러 - CPU 타임라인
  3. 앱에서 추적하려는 UI로 이동한 다음 System Trace를 선택하고 Record를 선택합니다.

    추적 옵션 - System Trace
    그림 4. 추적 옵션 - System Trace
  4. 앱에서 재구성을 유발한 다음 녹화를 중지합니다. 추적이 처리되고 표시되면 재구성 추적에서 컴포저블을 볼 수 있습니다. 키보드와 마우스를 사용하여 추적을 확대/축소하고 패닝할 수 있습니다. 추적을 살펴보는 데 익숙하지 않으면 트레이스 기록 문서를 참고하세요.

    시스템 추적
    그림 5. 시스템 추적

    차트에서 컴포저블을 더블클릭하면 소스 코드로 이동합니다.

  5. Flame Chart의 컴포저블도 파일 및 줄 번호와 함께 확인할 수 있습니다.

    Flame Chart
    그림 6. Flame Chart

주의사항

APK 크기 오버헤드

Google에서는 이 기능의 오버헤드를 가급적 최소화하려고 했지만, Compose 컴파일러가 APK에 삽입한 추적 문자열로 인해 Compose 앱의 APK 크기가 늘어납니다. 앱이 Compose를 많이 사용하지 않거나 Compose만 앱에서 비교적 많이 사용하지 않는 경우 늘어나는 크기가 비교적 작을 수 있습니다. 이러한 추적 문자열은 위 그림에서와 같이 추적 도구에 표시될 수 있도록 추가로 난독화 해제됩니다. Compose 컴파일러는 버전 1.3.0부터 모든 앱에 추적 문자열을 삽입합니다.

다음 proguard 규칙을 추가하여 프로덕션 빌드에서 추적 문자열을 삭제할 수 있습니다.

-assumenosideeffects public class androidx.compose.runtime.ComposerKt {

   boolean isTraceInProgress();

   void traceEventStart(int,int,int,java.lang.String);

   void traceEventStart(int,java.lang.String);

   void traceEventEnd();

}

이러한 함수는 추후 변경될 수 있으며, 모든 변경사항은 Compose 출시 노트에서 확인할 수 있습니다.

APK 크기가 늘어나는 대신 이러한 함수를 사용하면 앱 사용자가 실행하는 APK와 동일한 APK를 프로파일링할 수 있습니다.

정확한 타이밍

모든 성능 테스트가 그렇듯이 정확한 프로파일링을 위해서는 프로파일링 가능한 애플리케이션에 따라 앱을 profileablenon-debuggable로 만들어야 합니다.

터미널에서 트레이스 캡처

터미널에서 컴포지션 트레이스를 캡처할 수 있습니다. 이렇게 하려면 Android 스튜디오에서 일반적으로 자동으로 실행하는 단계를 실행해야 합니다.

종속 항목 추가

먼저 앱에 종속 항목을 추가합니다.

implementation("androidx.tracing:tracing-perfetto:1.0.0")
implementation("androidx.tracing:tracing-perfetto-binary:1.0.0")

레코드 명령어 생성

  1. Perfetto를 사용하여 레코드 명령어를 생성합니다.
  2. 다음 예와 같이 track_event 데이터 소스 섹션을 직접 추가합니다.

    adb shell perfetto \
      -c - --txt \
      -o /data/misc/perfetto-traces/trace \
    <<EOF
    buffers: {
        size_kb: 63488
        fill_policy: RING_BUFFER
    }
    buffers: {
        size_kb: 2048
        fill_policy: RING_BUFFER
    }
    data_sources: {
        config {
            name: "track_event"
        }
    }
    duration_ms: 10000
    flush_period_ms: 30000
    incremental_state_config {
        clear_period_ms: 5000
    }
    EOF
    

트레이스 캡처

  1. 앱을 실행하고 추적할 섹션을 준비합니다.
  2. 브로드캐스트를 실행하여 앱에서 추적을 사용 설정합니다.

    # set app package variable, e.g. com.google.samples.apps.nowinandroid.debug
    # can be found through `adb shell ps -ef` or `adb shell cmd package list packages`
    package=<your app process>
    
    # issue a broadcast to enable tracing
    adb shell am broadcast \
    -a androidx.tracing.perfetto.action.ENABLE_TRACING \
    $package/androidx.tracing.perfetto.TracingReceiver
    
  3. 이전에 만든 녹음 명령어를 시작합니다.

트레이스 열기

  1. 기기의 트레이스 (레코드 명령어에 지정된 위치)를 adb pull <location>합니다.

  2. Perfetto에서 엽니다.

Jetpack Macrobenchmark로 트레이스 캡처

트레이스를 결과로 제공하는 Jetpack Macrobenchmark를 사용하여 성능을 측정할 수 있습니다. macrobenchmarks를 사용하여 컴포지션 추적을 사용 설정하려면 다음을 실행해야 합니다.

  1. Macrobenchmark 테스트 모듈에 다음 종속 항목을 추가합니다.

    implementation("androidx.tracing:tracing-perfetto:1.0.0")
    implementation("androidx.tracing:tracing-perfetto-binary:1.0.0")
    
  2. 벤치마크를 실행하기 전에 androidx.benchmark.fullTracing.enable=true 계측 인수를 추가합니다. Macrobenchmark 계측 인수에 관한 자세한 내용은 Macrobenchmark 계측 인수를 참고하세요.

의견

이 기능 및 발견한 버그와 요청에 관한 의견을 보내주세요. Issue Tracker를 통해 의견을 보내주실 수 있습니다.