Skip to content

Commit

Permalink
Support baseline profile generation for coil-base. (#1572)
Browse files Browse the repository at this point in the history
* Create setupTestModule for the benchmarking module.

* Move Proguard files.

* Clean up.

* Update package.

* Fix compilation.

* Pass project name through.

* Update filtering.

* Suppress.

* Clean up scripts.

* Update publish script.

* Use pixel 6.
  • Loading branch information
colinrtwhite authored Dec 21, 2022
1 parent ab9813d commit 872c217
Show file tree
Hide file tree
Showing 27 changed files with 173 additions and 223 deletions.
3 changes: 2 additions & 1 deletion .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions assemble_baseline_profile.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

./gradlew :coil-benchmark:pixel6Api31BenchmarkAndroidTest -P android.testInstrumentationRunnerArguments.class=coil.benchmark.BaselineProfileGenerator#generate -Dproject=view
mv coil-benchmark/build/outputs/managed_device_android_test_additional_output/pixel6Api31/BaselineProfileGenerator_generate-baseline-prof.txt coil-base/src/main/baseline-prof.txt
./gradlew :coil-benchmark:pixel6Api31BenchmarkAndroidTest -P android.testInstrumentationRunnerArguments.class=coil.benchmark.BaselineProfileGenerator#generate -Dproject=compose
mv coil-benchmark/build/outputs/managed_device_android_test_additional_output/pixel6Api31/BaselineProfileGenerator_generate-baseline-prof.txt coil-compose-base/src/main/baseline-prof.txt
5 changes: 0 additions & 5 deletions baseline-profile.sh

This file was deleted.

19 changes: 16 additions & 3 deletions buildSrc/src/main/kotlin/Projects.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.android.build.api.dsl.CommonExtension
import com.android.build.api.dsl.Lint
import com.android.build.gradle.BaseExtension
import com.android.build.gradle.LibraryExtension
import com.android.build.gradle.TestExtension
import com.android.build.gradle.internal.dsl.BaseAppModuleExtension
import org.gradle.api.JavaVersion
import org.gradle.api.Project
Expand All @@ -21,7 +22,7 @@ fun Project.setupLibraryModule(
buildConfig: Boolean = false,
publish: Boolean = false,
document: Boolean = publish,
block: LibraryExtension.() -> Unit = {}
block: LibraryExtension.() -> Unit = {},
) = setupBaseModule<LibraryExtension>(name) {
libraryVariants.all {
generateBuildConfigProvider?.configure { enabled = buildConfig }
Expand Down Expand Up @@ -54,6 +55,7 @@ fun Project.setupAppModule(
block: BaseAppModuleExtension.() -> Unit = {}
) = setupBaseModule<BaseAppModuleExtension>(name) {
defaultConfig {
applicationId = name
versionCode = project.versionCode
versionName = project.versionName
resourceConfigurations += "en"
Expand All @@ -62,9 +64,20 @@ fun Project.setupAppModule(
block()
}

fun Project.setupTestModule(
name: String?,
block: TestExtension.() -> Unit = {},
) = setupBaseModule<TestExtension>(name) {
defaultConfig {
resourceConfigurations += "en"
vectorDrawables.useSupportLibrary = true
}
block()
}

private inline fun <reified T : BaseExtension> Project.setupBaseModule(
name: String?,
crossinline block: T.() -> Unit = {}
crossinline block: T.() -> Unit = {},
) = extensions.configure<T>("android") {
namespace = name
compileSdkVersion(project.compileSdk)
Expand All @@ -91,7 +104,7 @@ private inline fun <reified T : BaseExtension> Project.setupBaseModule(
"-Xno-param-assertions",
"-Xno-receiver-assertions",
)
if (project.name != "coil-test") {
if (project.name != "coil-benchmark" && project.name != "coil-test") {
arguments += "-opt-in=coil.annotation.ExperimentalCoilApi"
}
// https://youtrack.jetbrains.com/issue/KT-41985
Expand Down
48 changes: 48 additions & 0 deletions coil-benchmark/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import coil.setupTestModule
import com.android.build.api.dsl.ManagedVirtualDevice

plugins {
id("com.android.test")
id("kotlin-android")
}

setupTestModule(name = "coil.benchmark") {
val targetProject = System.getProperty("project", "view")
defaultConfig {
minSdk = 23
buildConfigField("String", "PROJECT", "\"$targetProject\"")
}
buildTypes {
create("benchmark") {
isDebuggable = true
signingConfig = getByName("debug").signingConfig
matchingFallbacks += listOf("release")
}
}
testOptions {
managedDevices {
devices {
create<ManagedVirtualDevice>("pixel6Api31") {
device = "Pixel 6"
apiLevel = 31
systemImageSource = "aosp"
}
}
}
}
targetProjectPath = ":coil-sample-$targetProject"
experimentalProperties["android.experimental.self-instrumenting"] = true
}

dependencies {
implementation(libs.androidx.benchmark.macro)
implementation(libs.androidx.test.espresso)
implementation(libs.androidx.test.junit)
implementation(libs.androidx.test.uiautomator)
}

androidComponents {
beforeVariants(selector().all()) {
it.enable = it.buildType == "benchmark"
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<queries>
<package android:name="sample.compose" />
<package android:name="sample.compose"/>
<package android:name="sample.view"/>
</queries>
</manifest>
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package coil.compose.benchmark
package coil.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
import androidx.test.ext.junit.runners.AndroidJUnit4
import coil.benchmark.BuildConfig.PROJECT
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class BaselineProfileBenchmark {

@get:Rule
val benchmarkRule = MacrobenchmarkRule()

Expand All @@ -22,17 +24,12 @@ class BaselineProfileBenchmark {

@Test
fun startupPartialCompilation() {
startup(CompilationMode.Partial(
baselineProfileMode = BaselineProfileMode.Disable,
warmupIterations = 3
))
startup(CompilationMode.Partial(BaselineProfileMode.Disable, warmupIterations = 3))
}

@Test
fun startupBaselineProfile() {
startup(CompilationMode.Partial(
baselineProfileMode = BaselineProfileMode.Require
))
startup(CompilationMode.Partial(BaselineProfileMode.Require))
}

@Test
Expand All @@ -42,16 +39,13 @@ class BaselineProfileBenchmark {

private fun startup(compilationMode: CompilationMode) {
benchmarkRule.measureRepeated(
packageName = "sample.compose",
packageName = "sample.$PROJECT",
metrics = listOf(StartupTimingMetric()),
iterations = 10,
startupMode = StartupMode.COLD,
compilationMode = compilationMode,
setupBlock = {
pressHome()
}
) {
startActivityAndWait()
}
setupBlock = { pressHome() },
measureBlock = { startActivityAndWait() },
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package coil.benchmark

import androidx.benchmark.macro.junit4.BaselineProfileRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Direction
import androidx.test.uiautomator.UiDevice
import coil.benchmark.BuildConfig.PROJECT
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
@Suppress("KotlinConstantConditions") // BuildConfig constant can change.
class BaselineProfileGenerator {

@get:Rule
val baselineProfileRule = BaselineProfileRule()

@Test
fun generate() = baselineProfileRule.collectBaselineProfile(
packageName = "sample.$PROJECT",
filterPredicate = newFilterPredicate(),
) {
pressHome()
startActivityAndWait()
UiDevice.getInstance(getInstrumentation())
.findObject(
if (PROJECT == "compose") {
By.res("list")
} else {
By.res(packageName, "list")
},
)
.fling(Direction.DOWN, 3000)
device.waitForIdle()
}

private fun newFilterPredicate(): (String) -> Boolean {
// Only include Compose-specific rules in the coil-compose module.
val packageName = if (PROJECT == "compose") "coil/compose/" else "coil/"
return { line -> packageName in line && "sample/" !in line }
}
}
1 change: 0 additions & 1 deletion coil-compose-benchmark/.gitignore

This file was deleted.

68 changes: 0 additions & 68 deletions coil-compose-benchmark/build.gradle.kts

This file was deleted.

This file was deleted.

File renamed without changes.
1 change: 0 additions & 1 deletion coil-sample-compose/baseline-profile-rules.pro

This file was deleted.

16 changes: 8 additions & 8 deletions coil-sample-compose/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@ plugins {
}

setupAppModule(name = "sample.compose") {
defaultConfig {
applicationId = "sample.compose"
}
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles("shrinker-rules.pro", "shrinker-rules-android.pro")
proguardFiles(
"../coil-sample-common/shrinker-rules.pro",
"../coil-sample-common/shrinker-rules-android.pro",
)
signingConfig = signingConfigs["debug"]
}

create("benchmark") {
signingConfig = signingConfigs.getByName("debug")
matchingFallbacks += listOf("release")
isDebuggable = false
proguardFiles("baseline-profile-rules.pro")
isMinifyEnabled = false
isShrinkResources = false
matchingFallbacks += listOf("release")
signingConfig = signingConfigs.getByName("debug")
}
}
buildFeatures {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,9 @@ private fun ListScreen(
val numColumns = remember(context) { numberOfColumns(context) }

LazyVerticalStaggeredGrid(
modifier = Modifier.testTag("scrollableContent"),
columns = StaggeredGridCells.Fixed(numColumns),
state = gridState,
modifier = Modifier.testTag("list"),
) {
items(images) { image ->
// Scale the image to fit the width of a column.
Expand Down
Loading

0 comments on commit 872c217

Please # to comment.