Macrobenchmark 작성

컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.

애플리케이션 시작과 복잡한 UI 조작(RecyclerView 스크롤 또는 애니메이션 실행)과 같이 애플리케이션의 대규모 사용 사례를 테스트하는 데 Macrobenchmark 라이브러리를 사용합니다. 코드의 작은 영역을 테스트하려면 Microbenchmark 라이브러리를 참고하세요.

라이브러리는 Android 스튜디오 콘솔과 JSON 파일 양쪽에 자세한 정보가 포함된 벤치마킹 결과를 출력합니다. 또한, Android 스튜디오에서 로드하고 분석할 수 있는 트레이스 파일도 제공합니다.

지속적 통합에서 벤치마크 실행에 설명한 대로 지속적 통합(CI) 환경에서 Macrobenchmark 라이브러리를 사용합니다.

Macrobenchmark를 사용하여 기준 프로필을 생성할 수 있습니다. 아래 가이드에 따라 Marcobenchmark 라이브러리를 설정한 다음 기준 프로필을 만듭니다.

프로젝트 설정

최신 버전의 IDE에는 Macrobenchmark와 통합된 새로운 기능이 있으므로, Macrobenchmark는 최신 버전의 Android 스튜디오(Bumblebee 2021.1.1 이상)와 함께 사용하는 것이 좋습니다.

Macrobenchmark 모듈 설정

매크로 벤치마크에는 앱 코드와 분리되어 앱 측정 테스트 실행을 담당하는 com.android.test 모듈이 필요합니다.

Bumblebee(또는 그 이상)

Android 스튜디오 Bumblebee 2021.1.1에는 Macrobenchmark 모듈 설정을 간소화할 수 있는 템플릿이 있습니다. 벤치마킹 모듈 템플릿은 샘플 시작 벤치마크를 포함해 앱 모듈에서 빌드한 앱을 측정할 수 있는 모듈을 프로젝트에 자동으로 생성합니다.

모듈 템플릿을 사용하여 새 모듈을 만들려면 다음 단계를 따르세요.

  1. Android 스튜디오의 Project 패널에서 프로젝트 또는 모듈을 마우스 오른쪽 버튼으로 클릭하고 New > Module을 클릭합니다.

  2. Template 창에서 Benchmark를 선택합니다.

  3. 새로운 macrobenchmark 모듈의 패키지 및 모듈 이름 외에도 타겟 애플리케이션(벤치마킹할 앱)을 맞춤설정할 수 있습니다.

  4. Finish를 클릭합니다.

벤치마크 모듈 템플릿

Arctic Fox

Arctic Fox에서는 라이브러리 모듈을 만들어 테스트 모듈로 변환합니다.

  1. Android 스튜디오의 Project 패널에서 프로젝트 또는 모듈을 마우스 오른쪽 버튼으로 클릭하고 New > Module을 클릭합니다.
  2. Templates 창에서 Android Library를 선택합니다.
  3. 모듈 이름으로 macrobenchmark를 입력합니다.
  4. Minimum SDKAPI 23: Android M으로 설정합니다.
  5. Finish를 클릭합니다.

새 라이브러리 모듈 구성

Gradle 파일 수정

Macrobenchmark 모듈의 build.gradle을 다음과 같이 맞춤설정합니다.

  1. 플러그인을 com.android.library에서 com.android.test로 변경합니다.
    apply plugin 'com.android.test'
  2. 그 밖에 필요한 테스트 모듈 속성을 android {} 블록에 추가합니다.

    Groovy

    android {
        // ...
        // Note that your module name may have different name
        targetProjectPath = ":app"
        // Enable the benchmark to run separately from the app process
        experimentalProperties["android.experimental.self-instrumenting"] = true
    
        buildTypes {
            // declare a build type to match the target app's build type
            benchmark {
                debuggable = true
                signingConfig = debug.signingConfig
            }
        }
    }
      

    Kotlin

    android {
        // ...
        // Note that your module name may have different name
        targetProjectPath = ":app"
        // Enable the benchmark to run separately from the app process
        experimentalProperties["android.experimental.self-instrumenting"] = true
    
        buildTypes {
            // declare a build type to match the target app's build type
            create("benchmark") {
                isDebuggable = true
                signingConfig = signingConfigs.getByName("debug")
            }
        }
    }
      

  3. testImplementation 또는 androidTestImplementation이라는 이름의 모든 종속 항목을 implementation으로 변경합니다.
  4. Macrobenchmark 라이브러리에 대한 종속 항목을 추가합니다.
    implementation 'androidx.benchmark:benchmark-macro-junit4:1.1.0-rc02'
  5. 이 모듈에 benchmark buildType만 허용합니다. android{} 블록 뒤, dependencies{} 블록 앞에 다음을 추가합니다.

    Groovy

    androidComponents {
        beforeVariants(selector().all()) {
            // enable only the benchmark buildType, since we only want to measure close to release performance
            enabled = buildType == 'benchmark'
        }
    }
      

    Kotlin

    androidComponents {
        beforeVariants {
            // enable only the benchmark buildType, since we only want to measure close to release performance
            it.enable = it.buildType == "benchmark"
        }
    }
      
  6. 디렉터리 구조 단순화

    com.android.test 모듈에서는 모든 테스트에 하나의 소스 디렉터리만을 사용합니다. src/testsrc/androidTest를 포함한 다른 소스 디렉터리는 사용하지 않으므로 삭제합니다.

애플리케이션 설정

앱(매크로 벤치마크의 타겟이라고 함)을 벤치마크하려면 앱이 profileable이어야 합니다. 그래야 자세한 트레이스 정보를 읽을 수 있습니다. 앱 AndroidManifest.xml<application> 태그에서 이를 사용 설정합니다.

<!-- enable profiling by macrobenchmark -->
<profileable
    android:shell="true"
    tools:targetApi="q" />

벤치마크된 앱은 가능한 한 출시 버전(또는 프로덕션)에 가깝게 구성합니다. 앱을 디버깅이 불가능하고 가급적 압축되도록 설정하면 성능이 향상됩니다. 이 작업은 일반적으로 실행은 동일하지만 디버그 키로 로컬에서 서명된 출시 변형의 복사본을 만들어 실행합니다. 또는 initWith를 사용하여 Gradle에 작업을 실행하도록 지시할 수 있습니다.

Groovy

buildTypes {
    release {
        minifyEnabled true
        shrinkResources true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }

    benchmark {
        initWith buildTypes.release
        signingConfig signingConfigs.debug

Kotlin

buildTypes {
    getByName("release") {
        isMinifyEnabled = true
        isShrinkResources = true
        proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"))
    }

    create("benchmark") {
        initWith(getByName("release"))
        signingConfig = signingConfigs.getByName("debug")
    }
}

Gradle 동기화를 실행하고 왼쪽에 있는 Build Variants 패널을 열고 앱과 Macrobenchmark 모듈의 벤치마크 변형을 각각 선택합니다. 그러면 벤치마크를 실행하여 앱의 정확한 변형을 빌드하고 테스트할 수 있습니다.

벤치마크 변형 선택

다중 모듈 애플리케이션 설정

앱에 Gradle 모듈이 2개 이상 있는 경우 빌드 스크립트가 컴파일할 빌드 변형을 알고 있어야 합니다. 해당하는 변형을 모르면 새로 추가된 benchmark buildType으로 인해 빌드가 실패하고 다음과 같은 오류 메시지가 표시됩니다.

> Could not resolve project :shared.
     Required by:
         project :app
      > No matching variant of project :shared was found.

matchingFallbacks 속성을 :macrobenchmark:app 모듈의 benchmark buildType에 추가하여 문제를 해결할 수 있습니다. 나머지 Gradle 모듈은 이전과 동일한 구성이면 됩니다.

Groovy

benchmark {
    initWith buildTypes.release
    signingConfig signingConfigs.debug

    matchingFallbacks = ['release']
}

Kotlin

create("benchmark") {
    initWith(getByName("release"))
    signingConfig = signingConfigs.getByName("debug")

    matchingFallbacks += listOf('release')
}

프로젝트에서 빌드 변형을 선택할 때, 다음 이미지에 보이는 것처럼 :app:macrobenchmark 모듈에는 benchmark를, 앱에 있는 다른 모듈에는 release를 선택합니다.

buildType으로 release 및 benchmark가 선택된 다중 모듈 프로젝트의 벤치마크 변형

자세한 내용은 변형 인식 종속 항목 관리를 참고하세요.

Macrobenchmark 클래스 만들기

벤치마크 테스트는 Macrobenchmark 라이브러리의 MacrobenchmarkRule JUnit4 규칙 API를 통해 제공됩니다. 이 API에는 타겟 애플리케이션이 실행되고 벤치마크되어야 하는 다양한 조건을 지정할 수 있는 measureRepeated 메서드가 포함되어 있습니다.

개발자는 최소한 타겟 애플리케이션의 packageName, 측정할 metrics, 벤치마크가 실행되어야 하는 iterations 횟수를 지정해야 합니다.

Kotlin

@LargeTest
@RunWith(AndroidJUnit4::class)
class SampleStartupBenchmark {
    @get:Rule
    val benchmarkRule = MacrobenchmarkRule()

    @Test
    fun startup() = benchmarkRule.measureRepeated(
        packageName = TARGET_PACKAGE,
        metrics = listOf(StartupTimingMetric()),
        iterations = 5,
        setupBlock = {
            // Press home button before each run to ensure the starting activity isn't visible.
            pressHome()
        }
    ) {
        // starts default launch activity
        startActivityAndWait()
    }
}

자바

@LargeTest
@RunWith(AndroidJUnit4.class)
public class SampleStartupBenchmark {
    @Rule
    public MacrobenchmarkRule benchmarkRule = new MacrobenchmarkRule();

    @Test
    public void startup() {
        benchmarkRule.measureRepeated(
            /* packageName */ TARGET_PACKAGE,
            /* metrics */ Arrays.asList(new StartupTimingMetric()),
            /* iterations */ 5,
            /* measureBlock */ scope -> {
                // starts default launch activity
                scope.startActivityAndWait();
                return Unit.INSTANCE;
            }
        );
    }
}

벤치마크 맞춤설정 방법에 관한 모든 옵션은 벤치마크 맞춤설정 섹션을 참고하세요.

벤치마크 실행

Android 스튜디오 내에서 테스트를 실행하여 기기에서 앱 성능을 측정합니다. 다음 이미지에서 보는 것처럼 테스트 클래스 또는 메서드 옆의 여백 작업을 사용하여 다른 @Test를 실행하는 것과 동일하게 벤치마크를 실행할 수 있습니다.

테스트 클래스 옆의 여백 작업으로 매크로 벤치마크 실행

다음과 같이 connectedCheck 명령어를 실행하여 명령줄에서 Gradle 모듈의 모든 벤치마크를 실행할 수도 있습니다.

./gradlew :macrobenchmark:connectedCheck

또는 다음과 같이 단일 테스트를 실행할 수 있습니다.

./gradlew :macrobenchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.macrobenchmark.startup.SampleStartupBenchmark#startup

지속적 통합으로 벤치마크를 실행하고 모니터링하는 방법에 관한 자세한 내용은 CI의 벤치마킹 섹션을 참고하세요.

벤치마크 결과

벤치마크 실행이 완료되면 측정항목이 Android 스튜디오에 직접 표시되고 CI 사용을 위해 JSON 파일로 출력됩니다. 측정된 반복마다 별개의 시스템 추적이 캡처됩니다. 다음 이미지와 같이 Test Results 창에 있는 링크 중 하나를 클릭하여 이러한 결과 트레이스를 열 수 있습니다.

Macrobenchmark 시작 결과

트레이스가 로드되면 분석할 프로세스를 선택하라는 메시지가 Android 스튜디오에 표시됩니다. 선택 항목은 타겟 앱 프로세스로 자동 입력됩니다.

스튜디오 트레이스 프로세스 선택

트레이스 파일이 로드되면 스튜디오의 CPU 프로파일러 도구에 결과가 표시됩니다.

스튜디오 트레이스

수동으로 트레이스 파일에 액세스

이전 버전의 Android 스튜디오를 사용하거나(Arctic Fox 2020.3.1 이전) Perfetto 도구를 사용하여 트레이스 파일을 분석하려는 경우 추가 단계가 있습니다. Perfetto는 트레이스 중에 기기에서 발생한 모든 프로세스를 검사하는 반면, Android 스튜디오의 CPU 프로파일러는 검사를 단일 프로세스로 제한합니다.

Android 스튜디오 또는 Gradle 명령줄을 사용하여 테스트를 호출하면 트레이스 파일이 기기에서 호스트로 자동 복사됩니다. 이러한 보고서는 호스트 머신의 다음 위치에 작성됩니다.

project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/TrivialStartupBenchmark_startup[mode=COLD]_iter002.perfetto-trace

호스트 시스템에 트레이스 파일이 있으면 Android 스튜디오 메뉴에서 File > Open을 선택하여 열 수 있습니다. 그러면 이전 섹션에 표시된 프로파일러 도구 뷰가 표시됩니다.

구성 오류

앱이 잘못 구성(디버그 가능 또는 프로파일링 불가)되면 Macrobenchmark는 부정확하거나 불완전한 측정을 보고하는 대신 오류를 반환합니다. androidx.benchmark.suppressErrors 인수를 사용하여 이러한 오류를 억제할 수 있습니다.

에뮬레이터를 측정하려고 하거나 기기에 배터리가 부족한 경우에도 코어 가용성 및 클록 속도가 저하될 수 있기 때문에 오류가 발생합니다.

벤치마크 맞춤설정

measureRepeated 함수는 라이브러리가 수집하는 측정항목, 애플리케이션 시작 및 컴파일 방식 또는 벤치마크가 실행되는 반복 횟수에 영향을 미치는 다양한 매개변수를 허용합니다.

측정항목 캡처

측정항목은 벤치마크에서 추출된 기본 정보 유형입니다. 사용 가능한 옵션은 StartupTimingMetric, FrameTimingMetric, TraceSectionMetric입니다. 이들에 대한 자세한 내용은 측정항목 캡처 페이지를 참고하세요.

맞춤 이벤트로 트레이스 데이터 개선

맞춤 트레이스 이벤트로 애플리케이션을 계측하는 것이 유용할 수 있습니다. 트레이스 보고서의 나머지 부분에 표시되는 맞춤 트레이스 이벤트는 앱에 특정 문제를 파악하는 데 도움이 될 수 있습니다. 맞춤 트레이스 이벤트의 생성 방법에 관한 자세한 내용은 맞춤 이벤트 정의 가이드를 참고하세요.

CompilationMode

매크로 벤치마크는 CompilationMode를 지정할 수 있습니다. 이 값은 DEX 바이트 코드(APK 내 바이트 코드 형식)에서 기계어 코드(사전 컴파일된 C++와 유사)로 미리 컴파일되어야 하는 앱의 양을 정의합니다.

기본적으로 매크로 벤치마크는 Android 7(API 수준 24) 이상에 기준 프로필(사용 가능한 경우)을 설치하는 CompilationMode.DEFAULT로 실행됩니다. Android 6(API 수준 23) 이하를 사용 중인 경우 컴파일 모드는 APK를 기본 시스템 동작으로 완전히 컴파일합니다.

타겟 애플리케이션에 기준 프로필과 ProfileInstaller 라이브러리가 모두 포함되어 있다면 기준 프로필을 설치할 수 있습니다.

Android 7 이상에서는 CompilationMode를 맞춤설정하여 다양한 수준의 AOT(Ahead-Of-Time) 컴파일 또는 JIT 캐싱을 모방하도록 기기 내 사전 컴파일 양에 영향을 줄 수 있습니다. CompilationMode.Full, CompilationMode.Partial, CompilationMode.None을 참고하세요.

이 기능은 ART 컴파일 명령어를 기반으로 빌드됩니다. 각 벤치마크는 벤치마크 간의 간섭을 방지하기 위해 벤치마크가 시작하기 전에 프로필 데이터를 삭제합니다.

StartupMode

활동 시작을 실행하려면 미리 정의된 시작 모드(COLD, WARM 또는 HOT 중 하나)를 전달하면 됩니다. 이 매개변수는 활동 시작 방식과 테스트 시작 시의 프로세스 상태를 변경합니다.

시작 유형에 관한 자세한 내용은 Android vitals 시작 문서를 참고하세요.

샘플

샘플 프로젝트는 GitHub에서 android/performance-samples 저장소의 일부로 사용할 수 있습니다.

의견 보내기

Jetpack Macrobenchmark에 관한 문제를 보고하거나 기능 요청을 제출하려면 공개 Issue Tracker를 참고하세요.