구글 공식문서 를 토대로 시키는 대로 했으나… 나의 경우 정상적으로 동작하지 않았다.
하여 내가 했던 방식을 정리해 보려고 한다.

먼저 Baseline Profile 을 사용할 수 있도록 모듈을 추가해주자.
구글 문서에 따라 모듈 중에서 Baseline Profile Generator 라는 모듈을 선택하여 설치해주도록 한다.
만약 에뮬레이터 에서 테스트를 원한다면 마지막에 Use Gradle Managed Device 를 선택해주면 된다.
이는 자동으로 정의되는 값이기 때문에, 별도로 만들고 싶다면 모듈 생성 후에 build.gradle 에서 수정하거나 추가할 수 있다.
나는 app 으로 테스트 할 예정이라 Target application 을 app 기준으로 했다. 만약 샘플앱이나 본인 프로젝트의 여러 모듈 별로 테스트를 하고 싶다면 아래 문서를 참고하면 된다.
https://velog.io/@hana/Android-Baseline-Profiles-정리2-Create-Baseline-Profiles
일단 위의 모듈 생성 팝업에서 finish 를 클릭하고 나면 본인이 설정한 모듈명을 토대로 (나의 경우 baselinemodule 으로) 모듈이 생성된 것을 확인할 수 있다.

여기서 BaselineProfileGenerator 클래스를 선택해보면 무언가 코드가 자동으로 짜여 있을 것이다.
코드의 내용을 잠깐 살펴보고 가자.
@RunWith(AndroidJUnit4::class)
@LargeTest
class BaselineProfileGenerator {
@get:Rule
val rule = BaselineProfileRule()
@Test
fun generate() {
// rule.collect() 의 매개변수에 packageName 는 필수값이다.
// 본인의 packageName 를 직접 넣을 수도 있다.
rule.collect(
packageName = InstrumentationRegistry.getArguments().getString("targetAppId")
?: throw Exception("targetAppId not passed as instrumentation runner arg"),
// 앱 시작과 관련된 테스트는 반드시 includeInStartProfile 이 true 로 설정된 규칙 블록 안에 있어야 하며,
// 반대로 앱 시작과 관련이 없는 테스트는 Startup Profile 에 포함되지 않도록 해야 최적의 성능을 유지할 수 있다
includeInStartupProfile = true
) {
// 기본적으로 앱을 실행하고, 앱의 첫번째 프레임이 렌더링 될 때까지 기다린디.
pressHome()
startActivityAndWait()
// 아래의 주석은 테스트해볼 수 있는 여러 예제들이다.
// nowInAndroid 앱에서 아래의 예제를 테스트 해볼 수 있다.
// https://github.com/android/nowinandroid
// For example:
// 1. Wait until the content is asynchronously loaded
// 2. Scroll the feed content
// 3. Navigate to detail screen
}
}
}

BaselineProfileGenerator 좌측의 run 를 실행해보자.
나의 경우 variants 를 all 로 선택하여 실행했는데, current 를 통해 현재 variant 로만 실행하고 싶다면 먼저 현재의 variant 를 release 로 지정하면 정상적으로 실행된다.


정상적으로 실행이 완료되었다면 output 에서 해당 정보를 확인할 수 있다.

대략 이렇게 build/outputs 아래에 basline 과 관련된 파일이 생겼다면, (아마) 실행이 되었다고 볼 수 있다.
파일의 네이밍은 본인의 단말, flavor 등에 의해 달라질 수 있다.
💡 배포모듈 생성 시 만들어진 클래스 중에 StartUpBenchmakrs 를 통해 성능이 얼마나 개선되었는지 확인할 수 있다.
여기서 Macrobenchmark 가 사용되었다는 것을 알 수 있다.
💡 Macrobenchmark 란?benchmark 가 동작하기 위해서는 app 모듈의 variant 를 benchmark 로 변경해 주어야 한다. 이 때 다른 모듈들은 자동으로 release 로 변경된다.

모듈을 통해 기본적으로 추가된 코드를 살펴보자.
@RunWith(AndroidJUnit4::class)
@LargeTest
class StartupBenchmarks {
@get:Rule
val rule = MacrobenchmarkRule()
@Test
fun startupCompilationNone() =
benchmark(CompilationMode.None())
@Test
fun startupCompilationBaselineProfiles() =
benchmark(CompilationMode.Partial(BaselineProfileMode.Require))
private fun benchmark(compilationMode: CompilationMode) {
// The application id for the running build variant is read from the instrumentation arguments.
rule.measureRepeated(
packageName = InstrumentationRegistry.getArguments().getString("targetAppId")
?: throw Exception("targetAppId not passed as instrumentation runner arg"),
metrics = listOf(StartupTimingMetric()),
compilationMode = compilationMode,
startupMode = StartupMode.COLD,
iterations = 10,
setupBlock = {
pressHome()
},
measureBlock = {
startActivityAndWait()
}
)
}
}
packgeName : 성능을 측정할 어플리케이션을 지정한다. 측정 대상을 선택해야 하기 때문에 무조건 지정이 필요하다.metrics : 측정하려는 정보 유형.interations : 벤치마크 테스트가 반복될 횟수. 많이 반복할 수록 안정성, 신뢰도가 높아지는 대신 실행 시간이 길어진다.startupMode : 벤치마크 시작 시 원하는 애플리케이션 시작 방식. Activity 시작 방식과 테스트 시작 시의 프로세스 상태를 변경할 수 있다.StartupMode.COLD : Startup Benchmark 에 사용한다. startupBlock 과 measureBlock 사이에 앱 프로세스를 종료한다.StartupMode.WARM : Frame timing Benchmark 에 사용한다. startupBlock 후에 프로세스가 종료되지 않는다. 프로세스를 종료하지 않고 모든 실행 중인 Activity 를 닫는다.StartupMode.HOT : 각 Activity 별 캐싱 매커니즘을 측정하는데 사용되며 프로세스나 이전에 실행 중이던 Activity 도 재시작 되지 않는다.Null : Macrobenchmark 가 아무곳도 하지 않는 모드. kiiProcess() 로 직접 컨트롤 한다.setUpBlock : 원하는 측정 화면 전에 할 동작 지정measureBlock : 벤치마크 중에 측정을 원하는 동작이외에도 ComplilationMode 를 퇘 컴파일 모드를 지정할 수 있다.
애플리케이션 성능을 최적화하려면 DEFAULT 모드를 선택하면 되는데, 이 옵션이 Google Play 에서 앱을 설치했을 때의 환경과 유사하다고 한다.
Baseline Profile 을 통해 제공되는 성능의 이점을 비교하고 싶다면 컴파일 모드 None 과 Parital 으로 비교하면 된다.
emulator 를 사용하고자 하는 경우android {
buildConfig {
testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "EMULATOR"
}
}
테스트를 실행하면 아래와 같이 결과를 확인할 수 있다. 모듈에서 자동으로 작성해준 코드는 앱이 처음 실행되었을 때 걸리는 시간을 측정한다.


결과를 보면 알 수 있듯이, BaselineProfile 을 사용한 것은 213.9ms 사용하지 않은 것은 259.4ms 로 차이가 있는 것을 확인할 수 있다.