Skip to content

Commit

Permalink
Setting up Macrobenchmarking and Baseline Profiles in Circuit (slackh…
Browse files Browse the repository at this point in the history
…q#250)

This PR setups a macrobenchmarking module to measure startup time with
and without a baseline profile. Measured on a Pixel 6, API 33.

**StartupBenchmark: Without Baseline Profile**
StartupBenchmark_startup
timeToInitialDisplayMs   min 219.4,   median 224.7,   max 240.8

**StartupBenhmark: With Baseline Profile**
StartupBenchmark_startup
timeToInitialDisplayMs   min 212.7,   median 215.4,   max 241.6

We are seeing about a 4% improvement with the min and median times. Zac
mentioned that because this is a pretty basic app, the performance wins
are not that apparent. Would be more apparent in a more complex app like
Slack!

Co-authored-by: Zac Sweers <[email protected]>
  • Loading branch information
iamritav and ZacSweers authored Nov 1, 2022
1 parent 826084e commit d63c1e3
Show file tree
Hide file tree
Showing 15 changed files with 1,194 additions and 31 deletions.
3 changes: 2 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
**/snapshots/**/*.png filter=lfs diff=lfs merge=lfs -text
**/snapshots/**/*.png filter=lfs diff=lfs merge=lfs -text
**/baseline-prof.txt linguist-generated=true
8 changes: 8 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.dsl.CommonExtension
import com.android.build.api.variant.LibraryAndroidComponentsExtension
import com.android.build.gradle.LibraryExtension
import com.android.build.gradle.TestExtension
import com.diffplug.gradle.spotless.SpotlessExtension
import com.diffplug.gradle.spotless.SpotlessExtensionPredeclare
import com.dropbox.gradle.plugins.dependencyguard.DependencyGuardPluginExtension
Expand Down Expand Up @@ -255,6 +256,13 @@ subprojects {
}
}

pluginManager.withPlugin("com.android.test") {
with(extensions.getByType<TestExtension>()) {
commonAndroidConfig()
defaultConfig { minSdk = 28 }
}
}

// Android app config
pluginManager.withPlugin("com.android.application") {
with(extensions.getByType<ApplicationExtension>()) {
Expand Down
267 changes: 267 additions & 0 deletions circuit/src/androidMain/baseline-prof.txt

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,12 @@ org.gradle.parallel=true

android.useAndroidX=true

# Otherwise this gets noisy warnings in android tests
android.enableAdditionalTestOutput=false

android.disableAutomaticComponentCreation=true

# Suppress warnings about experimental AGP properties we're using
# Ironically, this property itself is also experimental, so we have to suppress it too.
android.suppressUnsupportedOptionWarnings=android.suppressUnsupportedOptionWarnings,\
android.experimental.testOptions.emulatorSnapshots.maxSnapshotsForTestFailures,\
android.enableAdditionalTestOutput
android.experimental.testOptions.emulatorSnapshots.maxSnapshotsForTestFailures

# Disabled as this has no benefits in studio builds and only marginal benefits in command line, but
# can cause problems with Kotlin Gradle DSL. We're observing this for a week to see if/how it affects
Expand Down
6 changes: 6 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ agp = { module = "com.android.tools.build:gradle", version.ref = "agp" }
androidx-activity = { module = "androidx.activity:activity", version.ref = "androidx-activity" }
androidx-activity-ktx = { module = "androidx.activity:activity-ktx", version.ref = "androidx-activity" }
androidx-appCompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
androidx-benchmark-macro-junit = "androidx.benchmark:benchmark-macro-junit4:1.2.0-alpha06"
androidx-browser = { module = "androidx.browser:browser", version.ref = "androidx-browser" }
####### Compose
# You must enable the SlackProperties.enableCompose property to use these.
Expand Down Expand Up @@ -115,6 +116,11 @@ androidx-datastore-preferences = { module = "androidx.datastore:datastore-prefer

androidx-lifecycle-viewModel = { module = "androidx.lifecycle:lifecycle-viewmodel", version.ref = "androidx-lifecycle" }
androidx-lifecycle-viewModel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" }
androidx-profileinstaller = "androidx.profileinstaller:profileinstaller:1.3.0-alpha01"
androidx-test-espresso-core = "androidx.test.espresso:espresso-core:3.5.0-rc01"
androidx-test-ext-junit = "androidx.test.ext:junit:1.1.4-rc01"
androidx-test-uiautomator = "androidx.test.uiautomator:uiautomator:2.3.0-alpha01"

anvil-annotations = { module = "com.squareup.anvil:annotations", version.ref = "anvil" }

autoService-annotations = { module = "com.google.auto.service:auto-service-annotations", version = "1.0.1" }
Expand Down
23 changes: 22 additions & 1 deletion samples/star/apk/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,27 @@ android {
versionCode = 1
versionName = "1"
}
buildTypes {
val releaseBuildType =
getByName("release") {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
file("proguard-rules.pro")
)
}

create("benchmark") {
initWith(releaseBuildType)
signingConfig = signingConfigs.getByName("debug")
matchingFallbacks += listOf("release")
isDebuggable = false
}
}
}

dependencies { implementation(projects.samples.star) }
dependencies {
api(projects.samples.star)
implementation(libs.androidx.profileinstaller)
}
2 changes: 2 additions & 0 deletions samples/star/apk/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Can't obfuscate when generating baseline profiles
-dontobfuscate
33 changes: 11 additions & 22 deletions samples/star/apk/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,29 +1,18 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (C) 2022 Slack Technologies, LLC
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<application
android:label="Social Tees Animal Rescue"
android:name="com.slack.circuit.star.StarApp"
android:appComponentFactory="com.slack.circuit.star.di.StarAppComponentFactory"
android:enableOnBackInvokedCallback="true"
android:icon="@mipmap/ic_launcher"
android:label="Social Tees Animal Rescue"
android:theme="@style/StarTheme"
android:enableOnBackInvokedCallback="true"
android:appComponentFactory="com.slack.circuit.star.di.StarAppComponentFactory"
tools:replace="android:appComponentFactory" />
tools:replace="android:appComponentFactory">
<profileable
android:shell="true"
tools:targetApi="29" />
</application>

</manifest>
52 changes: 52 additions & 0 deletions samples/star/benchmark/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (C) 2022 Slack Technologies, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
plugins {
id("com.android.test")
kotlin("android")
}

android {
namespace = "com.circuit.samples.star.benchmark"
defaultConfig {
targetSdk = 33
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
// This benchmark buildType is used for benchmarking, and should function like your
// release build (for example, with minification on). It"s signed with a debug key
// for easy local/CI testing.
create("benchmark") {
isDebuggable = true
signingConfig = getByName("debug").signingConfig
matchingFallbacks += listOf("release")
}
}

targetProjectPath = ":samples:star:apk"
experimentalProperties["android.experimental.self-instrumenting"] = true
}

dependencies {
implementation(libs.androidx.compose.runtime)
implementation(libs.androidx.test.ext.junit)
implementation(libs.androidx.test.espresso.core)
implementation(libs.androidx.test.uiautomator)
implementation(libs.androidx.benchmark.macro.junit)
implementation(libs.androidx.profileinstaller)
}

androidComponents { beforeVariants { it.enable = it.buildType == "benchmark" } }
7 changes: 7 additions & 0 deletions samples/star/benchmark/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<queries>
<package android:name="com.slack.circuit.sample.star.apk" />
</queries>
</manifest>
Loading

0 comments on commit d63c1e3

Please sign in to comment.