From c99a544304411e5abfc44e5ccf0f5f56fa2ed7b6 Mon Sep 17 00:00:00 2001 From: Sad Ellie Date: Fri, 19 Jan 2024 17:09:07 +0300 Subject: [PATCH] Baseline profile setup --- README.md | 21 ++++++++++++++ app/benchmark-rules.pro | 6 ++++ app/build.gradle.kts | 15 +++++++++- benchmark/build.gradle.kts | 4 +-- .../unitto/benchmark/StartupBenchmark.kt | 29 ++++++++++++++++--- gradle/libs.versions.toml | 2 ++ 6 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 app/benchmark-rules.pro diff --git a/README.md b/README.md index ba0cbab4..14c47e92 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,27 @@ Read [this](https://github.com/sadellie/unitto/wiki/Security). ## 🤖 Custom ROM developers Leave. +## 🤓 Nerds + +
+Benchmarks and Baseline profile + +``` +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 +``` +
+ ## 🔎 Additional Terms and Conditions: https://sadellie.github.io/unitto/terms diff --git a/app/benchmark-rules.pro b/app/benchmark-rules.pro new file mode 100644 index 00000000..5fa87d01 --- /dev/null +++ b/app/benchmark-rules.pro @@ -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 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 430b5cda..9e97ae09 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -24,6 +24,7 @@ plugins { id("unitto.android.application.jacoco") id("jacoco") id("unitto.android.hilt") + alias(libs.plugins.baselineprofile) } android { @@ -73,8 +74,11 @@ android { } create("benchmark") { initWith(buildTypes.getByName("release")) + matchingFallbacks.add("release") signingConfig = signingConfigs.getByName("debug") - matchingFallbacks += listOf("release") + // Only use benchmark proguard rules + proguardFiles("benchmark-rules.pro") + isMinifyEnabled = true } } @@ -122,6 +126,7 @@ tasks.withType().configureEach dependencies { implementation(libs.androidx.core.core.ktx) + implementation(libs.androidx.profileinstaller.profileinstaller) coreLibraryDesugaring(libs.com.android.tools.desugar.jdk.libs) implementation(libs.androidx.compose.material3) @@ -144,4 +149,12 @@ dependencies { implementation(project(":data:userprefs")) implementation(project(":core:ui")) 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 } diff --git a/benchmark/build.gradle.kts b/benchmark/build.gradle.kts index 7e257d9b..c9ea266a 100644 --- a/benchmark/build.gradle.kts +++ b/benchmark/build.gradle.kts @@ -38,8 +38,8 @@ android { // for easy local/CI testing. create("benchmark") { isDebuggable = true - signingConfig = getByName("debug").signingConfig - matchingFallbacks += listOf("release") + signingConfig = signingConfigs.getByName("debug") + matchingFallbacks.add("release") } } diff --git a/benchmark/src/main/java/com/sadellie/unitto/benchmark/StartupBenchmark.kt b/benchmark/src/main/java/com/sadellie/unitto/benchmark/StartupBenchmark.kt index 6b1f7b20..a69e6fd3 100644 --- a/benchmark/src/main/java/com/sadellie/unitto/benchmark/StartupBenchmark.kt +++ b/benchmark/src/main/java/com/sadellie/unitto/benchmark/StartupBenchmark.kt @@ -18,6 +18,8 @@ package com.sadellie.unitto.benchmark +import androidx.benchmark.macro.BaselineProfileMode +import androidx.benchmark.macro.CompilationMode import androidx.benchmark.macro.StartupMode import androidx.benchmark.macro.StartupTimingMetric import androidx.benchmark.macro.junit4.MacrobenchmarkRule @@ -44,13 +46,32 @@ class StartupBenchmark { val benchmarkRule = MacrobenchmarkRule() @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", metrics = listOf(StartupTimingMetric()), - iterations = 5, - startupMode = StartupMode.COLD + compilationMode = compilationMode, + iterations = 10, + startupMode = StartupMode.COLD, + setupBlock = { + pressHome() + } ) { - pressHome() startActivityAndWait() } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index afdf530b..0f36b56a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -16,6 +16,7 @@ androidxHiltHiltNavigationCompose = "1.1.0" androidxMacroBenchmark = "1.2.2" androidxLifecycleLifecycleRuntimeCompose = "2.7.0" androidxNavigationNavigationCompose = "2.7.6" +androidxProfileinstallerProfileinstaller = "1.3.1" androidxRoom = "2.6.1" androidxTest = "1.5.0" 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-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-profileinstaller-profileinstaller = { group = "androidx.profileinstaller", name = "profileinstaller", version.ref = "androidxProfileinstallerProfileinstaller" } 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-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "androidxRoom" }