Baseline profile setup

This commit is contained in:
Sad Ellie 2024-01-19 17:09:07 +03:00
parent c1dce24645
commit c99a544304
6 changed files with 70 additions and 7 deletions

View File

@ -40,6 +40,27 @@ Read [this](https://github.com/sadellie/unitto/wiki/Security).
## 🤖 Custom ROM developers ## 🤖 Custom ROM developers
Leave. Leave.
## 🤓 Nerds
<details>
<summary>Benchmarks and Baseline profile</summary>
```
Pixel 8 - 14
StartupBenchmark_startupPrecompiledWithBaselineProfile
timeToInitialDisplayMs min 183.5, median 219.9, max 247.3
StartupBenchmark_startupWithoutPreCompilation
timeToInitialDisplayMs min 223.6, median 328.0, max 663.8
StartupBenchmark_startupWithPartialCompilationAndDisabledBaselineProfile
timeToInitialDisplayMs min 264.8, median 308.0, max 376.1
StartupBenchmark_startupFullyPrecompiled
timeToInitialDisplayMs min 314.4, median 336.9, max 388.3
```
</details>
## 🔎 Additional ## 🔎 Additional
Terms and Conditions: https://sadellie.github.io/unitto/terms Terms and Conditions: https://sadellie.github.io/unitto/terms

6
app/benchmark-rules.pro Normal file
View File

@ -0,0 +1,6 @@
# Proguard rules for the `benchmark` build type.
#
# Obsfuscation must be disabled for the build variant that generates Baseline Profile, otherwise
# wrong symbols would be generated. The generated Baseline Profile will be properly applied when generated
# without obfuscation and your app is being obfuscated.
-dontobfuscate

View File

@ -24,6 +24,7 @@ plugins {
id("unitto.android.application.jacoco") id("unitto.android.application.jacoco")
id("jacoco") id("jacoco")
id("unitto.android.hilt") id("unitto.android.hilt")
alias(libs.plugins.baselineprofile)
} }
android { android {
@ -73,8 +74,11 @@ android {
} }
create("benchmark") { create("benchmark") {
initWith(buildTypes.getByName("release")) initWith(buildTypes.getByName("release"))
matchingFallbacks.add("release")
signingConfig = signingConfigs.getByName("debug") signingConfig = signingConfigs.getByName("debug")
matchingFallbacks += listOf("release") // Only use benchmark proguard rules
proguardFiles("benchmark-rules.pro")
isMinifyEnabled = true
} }
} }
@ -122,6 +126,7 @@ tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach
dependencies { dependencies {
implementation(libs.androidx.core.core.ktx) implementation(libs.androidx.core.core.ktx)
implementation(libs.androidx.profileinstaller.profileinstaller)
coreLibraryDesugaring(libs.com.android.tools.desugar.jdk.libs) coreLibraryDesugaring(libs.com.android.tools.desugar.jdk.libs)
implementation(libs.androidx.compose.material3) implementation(libs.androidx.compose.material3)
@ -144,4 +149,12 @@ dependencies {
implementation(project(":data:userprefs")) implementation(project(":data:userprefs"))
implementation(project(":core:ui")) implementation(project(":core:ui"))
implementation(project(":core:base")) implementation(project(":core:base"))
baselineProfile(project(":benchmark"))
}
baselineProfile {
// Don't build on every iteration of a full assemble.
// Instead enable generation directly for the release build variant.
automaticGenerationDuringBuild = false
} }

View File

@ -38,8 +38,8 @@ android {
// for easy local/CI testing. // for easy local/CI testing.
create("benchmark") { create("benchmark") {
isDebuggable = true isDebuggable = true
signingConfig = getByName("debug").signingConfig signingConfig = signingConfigs.getByName("debug")
matchingFallbacks += listOf("release") matchingFallbacks.add("release")
} }
} }

View File

@ -18,6 +18,8 @@
package com.sadellie.unitto.benchmark package com.sadellie.unitto.benchmark
import androidx.benchmark.macro.BaselineProfileMode
import androidx.benchmark.macro.CompilationMode
import androidx.benchmark.macro.StartupMode import androidx.benchmark.macro.StartupMode
import androidx.benchmark.macro.StartupTimingMetric import androidx.benchmark.macro.StartupTimingMetric
import androidx.benchmark.macro.junit4.MacrobenchmarkRule import androidx.benchmark.macro.junit4.MacrobenchmarkRule
@ -44,13 +46,32 @@ class StartupBenchmark {
val benchmarkRule = MacrobenchmarkRule() val benchmarkRule = MacrobenchmarkRule()
@Test @Test
fun startup() = benchmarkRule.measureRepeated( fun startupWithoutPreCompilation() = startup(CompilationMode.None())
@Test
fun startupWithPartialCompilationAndDisabledBaselineProfile() = startup(
CompilationMode.Partial(baselineProfileMode = BaselineProfileMode.Disable, warmupIterations = 1),
)
@Test
fun startupPrecompiledWithBaselineProfile() =
startup(CompilationMode.Partial(baselineProfileMode = BaselineProfileMode.Require))
@Test
fun startupFullyPrecompiled() = startup(CompilationMode.Full())
private fun startup(
compilationMode: CompilationMode
) = benchmarkRule.measureRepeated(
packageName = "com.sadellie.unitto", packageName = "com.sadellie.unitto",
metrics = listOf(StartupTimingMetric()), metrics = listOf(StartupTimingMetric()),
iterations = 5, compilationMode = compilationMode,
startupMode = StartupMode.COLD iterations = 10,
) { startupMode = StartupMode.COLD,
setupBlock = {
pressHome() pressHome()
}
) {
startActivityAndWait() startActivityAndWait()
} }
} }

View File

@ -16,6 +16,7 @@ androidxHiltHiltNavigationCompose = "1.1.0"
androidxMacroBenchmark = "1.2.2" androidxMacroBenchmark = "1.2.2"
androidxLifecycleLifecycleRuntimeCompose = "2.7.0" androidxLifecycleLifecycleRuntimeCompose = "2.7.0"
androidxNavigationNavigationCompose = "2.7.6" androidxNavigationNavigationCompose = "2.7.6"
androidxProfileinstallerProfileinstaller = "1.3.1"
androidxRoom = "2.6.1" androidxRoom = "2.6.1"
androidxTest = "1.5.0" androidxTest = "1.5.0"
androidxTestExtJunitKtx = "1.1.5" androidxTestExtJunitKtx = "1.1.5"
@ -57,6 +58,7 @@ androidx-datastore-datastore-preferences = { group = "androidx.datastore", name
androidx-hilt-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "androidxHiltHiltNavigationCompose" } androidx-hilt-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "androidxHiltHiltNavigationCompose" }
androidx-lifecycle-lifecycle-runtime-compose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidxLifecycleLifecycleRuntimeCompose" } androidx-lifecycle-lifecycle-runtime-compose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidxLifecycleLifecycleRuntimeCompose" }
androidx-navigation-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "androidxNavigationNavigationCompose" } androidx-navigation-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "androidxNavigationNavigationCompose" }
androidx-profileinstaller-profileinstaller = { group = "androidx.profileinstaller", name = "profileinstaller", version.ref = "androidxProfileinstallerProfileinstaller" }
androidx-room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "androidxRoom" } androidx-room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "androidxRoom" }
androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "androidxRoom" } androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "androidxRoom" }
androidx-room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "androidxRoom" } androidx-room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "androidxRoom" }