-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support to generate baseline profiles for lottie and lottie-compo…
- Loading branch information
Showing
36 changed files
with
1,218 additions
and
677 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import static de.fayard.refreshVersions.core.Versions.versionFor | ||
|
||
plugins { | ||
id 'com.android.application' | ||
id "org.jetbrains.kotlin.android" | ||
id 'androidx.baselineprofile' | ||
} | ||
|
||
android { | ||
namespace 'com.airbnb.lottie.benchmark.app' | ||
compileSdk 34 | ||
defaultConfig { | ||
applicationId "com.airbnb.lottie.benchmark.app" | ||
minSdk 21 | ||
targetSdk 34 | ||
versionCode 1 | ||
versionName "1.0" | ||
} | ||
buildTypes { | ||
release { | ||
minifyEnabled false | ||
signingConfig signingConfigs.debug | ||
debuggable false | ||
proguardFiles("proguard-rules.pro") | ||
} | ||
create("benchmark") { | ||
initWith(release) | ||
signingConfig = signingConfigs.getByName("debug") | ||
} | ||
} | ||
buildFeatures { | ||
compose true | ||
} | ||
composeOptions { | ||
kotlinCompilerExtensionVersion = versionFor(project, AndroidX.compose.compiler) | ||
} | ||
} | ||
|
||
dependencies { | ||
implementation project(':lottie-compose') | ||
implementation libs.androidx.appcompat | ||
implementation libs.androidx.activity.compose | ||
implementation platform(libs.compose.bom) | ||
implementation libs.compose.ui | ||
implementation libs.compose.material | ||
implementation libs.compose.material.icons.extended | ||
implementation libs.compose.ui.tooling | ||
// Need this to side load a Baseline Profile when Benchmarking | ||
implementation libs.profileinstaller | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Proguard rules that are applied to your test apk/code. | ||
-dontoptimize | ||
-dontobfuscate | ||
-dontshrink | ||
-ignorewarnings | ||
-dontwarn * | ||
-dontnote * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> | ||
|
||
<application | ||
android:icon="@mipmap/ic_launcher" | ||
android:label="@string/app_name" | ||
android:theme="@style/Theme.AppCompat.Light.NoActionBar"> | ||
<profileable android:shell="true" /> | ||
|
||
<activity | ||
android:name=".BenchmarkActivity" | ||
android:exported="true"> | ||
<intent-filter> | ||
<action android:name="android.intent.action.MAIN" /> | ||
<category android:name="android.intent.category.LAUNCHER" /> | ||
</intent-filter> | ||
</activity> | ||
</application> | ||
</manifest> |
28 changes: 28 additions & 0 deletions
28
app-benchmark/src/main/kotlin/com/airbnb/lottie/benchmark/app/BenchmarkActivity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.airbnb.lottie.benchmark.app | ||
|
||
import android.os.Bundle | ||
import androidx.activity.compose.setContent | ||
import androidx.appcompat.app.AppCompatActivity | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.getValue | ||
import com.airbnb.lottie.compose.LottieAnimation | ||
import com.airbnb.lottie.compose.LottieCompositionSpec | ||
import com.airbnb.lottie.compose.LottieConstants | ||
import com.airbnb.lottie.compose.animateLottieCompositionAsState | ||
import com.airbnb.lottie.compose.rememberLottieComposition | ||
|
||
class BenchmarkActivity : AppCompatActivity() { | ||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
setContent { | ||
Content() | ||
} | ||
} | ||
|
||
@Composable | ||
fun Content() { | ||
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.benchmark)) | ||
val progress by animateLottieCompositionAsState(composition, iterations = LottieConstants.IterateForever) | ||
LottieAnimation(composition, { progress }) | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<resources> | ||
<string name="app_name">Lottie Benchmark</string> | ||
</resources> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import com.android.build.api.dsl.ManagedVirtualDevice | ||
|
||
plugins { | ||
id 'com.android.test' | ||
id 'org.jetbrains.kotlin.android' | ||
id 'androidx.baselineprofile' | ||
} | ||
|
||
android { | ||
namespace 'com.airbnb.lottie.baselineprofile' | ||
compileSdk 34 | ||
|
||
defaultConfig { | ||
minSdk 28 | ||
targetSdk 34 | ||
|
||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||
testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "EMULATOR" | ||
} | ||
|
||
targetProjectPath = ":app-benchmark" | ||
|
||
testOptions.managedDevices.devices { | ||
pixel6Api34(ManagedVirtualDevice) { | ||
device = "Pixel 6" | ||
apiLevel = 34 | ||
systemImageSource = "google" | ||
} | ||
} | ||
} | ||
|
||
baselineProfile { | ||
managedDevices += "pixel6Api34" | ||
useConnectedDevices = false | ||
} | ||
|
||
dependencies { | ||
implementation libs.okio | ||
implementation libs.androidx.test.junit | ||
implementation libs.androidx.test.espresso | ||
implementation libs.androidx.test.uiautomator | ||
implementation libs.androidx.test.macrobenchmark | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<manifest /> |
32 changes: 32 additions & 0 deletions
32
baselineprofile/src/main/java/com/airbnb/lottie/baselineprofile/BaselineProfileGenerator.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.airbnb.lottie.baselineprofile | ||
|
||
import androidx.benchmark.macro.junit4.BaselineProfileRule | ||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
import androidx.test.filters.LargeTest | ||
import org.junit.Rule | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
|
||
/** | ||
* You can run the generator with the Generate Baseline Profile gradle task. | ||
* ``` | ||
* ./gradlew :lottie(-compose):generateReleaseBaselineProfile -Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=BaselineProfile | ||
* ``` | ||
* | ||
* After you run the generator, you can verify the improvements running the [StartupBenchmarks] benchmark. | ||
**/ | ||
@RunWith(AndroidJUnit4::class) | ||
@LargeTest | ||
class BaselineProfileGenerator { | ||
|
||
@get:Rule | ||
val rule = BaselineProfileRule() | ||
|
||
@Test | ||
fun generate() { | ||
rule.collect("com.airbnb.lottie.benchmark.app") { | ||
pressHome() | ||
startActivityAndWait() | ||
} | ||
} | ||
} |
69 changes: 69 additions & 0 deletions
69
baselineprofile/src/main/java/com/airbnb/lottie/baselineprofile/StartupBenchmarks.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package com.airbnb.lottie.baselineprofile | ||
|
||
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 androidx.test.filters.LargeTest | ||
import org.junit.Rule | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
|
||
/** | ||
* This test class benchmarks the speed of app startup. | ||
* Run this benchmark to verify how effective a Baseline Profile is. | ||
* It does this by comparing [CompilationMode.None], which represents the app with no Baseline | ||
* Profiles optimizations, and [CompilationMode.Partial], which uses Baseline Profiles. | ||
* | ||
* Run this benchmark to see startup measurements and captured system traces for verifying | ||
* the effectiveness of your Baseline Profiles. You can run it directly from Android | ||
* Studio as an instrumentation test, or run all benchmarks with this Gradle task: | ||
* ``` | ||
* ./gradlew :baselineprofile:connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=Macrobenchmark | ||
* ``` | ||
* | ||
* You should run the benchmarks on a physical device, not an Android emulator, because the | ||
* emulator doesn't represent real world performance and shares system resources with its host. | ||
* | ||
* For more information, see the [Macrobenchmark documentation](https://d.android.com/macrobenchmark#create-macrobenchmark) | ||
* and the [instrumentation arguments documentation](https://d.android.com/topic/performance/benchmarking/macrobenchmark-instrumentation-args). | ||
* | ||
* Note that the performance impact of this test is only tangentially related to the impact of the baseline profile for Lottie. | ||
* The benefit of the baseline profile for Lottie is less about startup time and more about time spent running the hot path | ||
* of the Lottie rendering code. | ||
* | ||
* Ideally, this test would be updated to reflect that rather than just startup time but that's a task for another time… | ||
**/ | ||
@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) { | ||
rule.measureRepeated( | ||
packageName = "com.airbnb.lottie.benchmark.app", | ||
metrics = listOf(StartupTimingMetric()), | ||
compilationMode = compilationMode, | ||
startupMode = StartupMode.COLD, | ||
iterations = 10, | ||
setupBlock = { | ||
pressHome() | ||
}, | ||
measureBlock = { | ||
startActivityAndWait() | ||
} | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
plugins { | ||
id 'com.android.test' | ||
id 'org.jetbrains.kotlin.android' | ||
id 'androidx.baselineprofile' | ||
} | ||
|
||
android { | ||
namespace 'com.airbnb.lottie.benchmark' | ||
compileSdk 34 | ||
|
||
kotlinOptions { | ||
freeCompilerArgs += "-opt-in=kotlin.RequiresOptIn" | ||
} | ||
|
||
defaultConfig { | ||
minSdk 30 | ||
targetSdk 34 | ||
|
||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||
} | ||
|
||
buildTypes { | ||
release { | ||
debuggable = true | ||
signingConfig = debug.signingConfig | ||
} | ||
} | ||
|
||
targetProjectPath = ":app-benchmark" | ||
experimentalProperties["android.experimental.self-instrumenting"] = true | ||
|
||
testOptions.managedDevices.devices { | ||
pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) { | ||
device = "Pixel 6" | ||
apiLevel = 31 | ||
systemImageSource = "aosp" | ||
} | ||
} | ||
} | ||
|
||
baselineProfile { | ||
managedDevices += "pixel6Api31" | ||
useConnectedDevices = false | ||
} | ||
|
||
dependencies { | ||
implementation libs.androidx.test.junit | ||
implementation libs.androidx.test.espresso | ||
implementation libs.androidx.test.uiautomator | ||
implementation libs.androidx.test.macrobenchmark | ||
implementation libs.compose.ui.test.junit | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
Oops, something went wrong.