AndroidX Core Team | 0e7745f | 2021-04-08 17:00:10 +0000 | [diff] [blame] | 1 | # Benchmarking in AndroidX |
| 2 | |
| 3 | [TOC] |
| 4 | |
| 5 | <!-- Copied from macrobenchmark docs --> |
| 6 | |
| 7 | <table> |
| 8 | <tr> |
| 9 | <td><strong>Macrobenchmark</strong> (new!)</td> |
| 10 | <td><strong>Benchmark</strong> (existing!)</td> |
| 11 | </tr> |
| 12 | <tr> |
| 13 | <td>Measure high-level entry points (Activity launch / Scrolling a list)</td> |
| 14 | <td>Measure individual functions</td> |
| 15 | </tr> |
| 16 | <tr> |
| 17 | <td>Out-of-process test of full app</td> |
| 18 | <td>In-process test of CPU work</td> |
| 19 | </tr> |
| 20 | <tr> |
| 21 | <td>Slow iteration speed (Often several minutes)</td> |
| 22 | <td>Fast iteration speed (Often less than 10 seconds)</td> |
| 23 | </tr> |
| 24 | <tr> |
| 25 | <td>Results come with profiling traces</td> |
| 26 | <td>Optional method sampling/tracing</td> |
| 27 | </tr> |
| 28 | <tr> |
| 29 | <td>Min API 29</td> |
| 30 | <td>Min API 14</td> |
| 31 | </tr> |
| 32 | </table> |
| 33 | |
| 34 | The |
| 35 | [public documentation](https://android.googlesource.com/platform/frameworks/support/+/androidx-main/benchmark/docs/macrobenchmark.md) |
| 36 | for macrobenchmark explains how to use the library. This page focuses on |
| 37 | specifics to writing library macrobenchmarks in the AndroidX repo. If you're |
| 38 | looking for measuring CPU perf of individual functions, see the guide for |
| 39 | MICRObenchmarks [here](benchmarking). |
| 40 | |
| 41 | ### Writing the benchmark |
| 42 | |
| 43 | Benchmarks are just regular instrumentation tests! Just use the |
| 44 | [`MacrobenchmarkRule`](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:benchmark/macro-junit4/src/main/java/androidx/benchmark/macro/junit4/MacrobenchmarkRule.kt) |
| 45 | provided by the library: |
| 46 | |
| 47 | <section class="tabs"> |
| 48 | |
| 49 | #### Kotlin {.new-tab} |
| 50 | |
| 51 | ```kotlin |
| 52 | @RunWith(AndroidJUnit4::class) |
| 53 | class MyStartupBenchmark { |
| 54 | @get:Rule |
| 55 | val benchmarkRule = MacrobenchmarkRule() |
| 56 | |
| 57 | @Test |
| 58 | fun startup() = benchmarkRule.measureRepeated( |
| 59 | packageName = "mypackage.myapp", |
| 60 | metrics = listOf(StartupTimingMetric()), |
| 61 | startupMode = StartupMode.COLD, |
| 62 | iterations = 5 |
| 63 | ) { // this = MacrobenchmarkScope |
| 64 | pressHome() |
| 65 | val intent = Intent() |
| 66 | intent.setPackage("mypackage.myapp") |
| 67 | intent.setAction("mypackage.myapp.myaction") |
| 68 | startActivityAndWait(intent) |
| 69 | } |
| 70 | } |
| 71 | ``` |
| 72 | |
| 73 | #### Java {.new-tab} |
| 74 | |
| 75 | ```java |
| 76 | // TODO: Java APIs are not yet available. |
| 77 | ``` |
| 78 | |
| 79 | </section> |
| 80 | |
| 81 | ## Project structure |
| 82 | |
| 83 | As in the public documentation, macrobenchmarks in the AndroidX repo are |
| 84 | comprised of an app, and a separate macrobenchmark module. Additional setups |
| 85 | steps/constraints for the AndroidX repository are listed below. |
| 86 | |
| 87 | 1. App and macrobenchmark modules must be unique, and map 1:1. |
| 88 | |
| 89 | 1. Target app path in `settings.gradle` must end with |
| 90 | `:integration-tests:macrobenchmark-target`. |
| 91 | |
| 92 | 1. Macrobenchmark library path must be at the same path, but instead ending |
| 93 | with `:integration-tests:macrobenchmark` |
| 94 | |
| 95 | 1. An entry should be placed in AffectedModuleDetector to recognize |
| 96 | macrobenchmark dependency on target app module, |
| 97 | [for example](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:buildSrc/src/main/kotlin/androidx/build/dependencyTracker/AffectedModuleDetector.kt;l=518;drc=cfb504756386b6225a2176d1d6efe2f55d4fa564) |
| 98 | |
| 99 | Compose Macrobenchmark Examples: |
| 100 | |
| 101 | * [`:compose:integration-tests:macrobenchmark-target`](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/integration-tests/macrobenchmark-target/) |
| 102 | |
| 103 | * [`:compose:integration-tests:macrobenchmark`](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/integration-tests/macrobenchmark/) |
| 104 | |
| 105 | * [AffectedModuleDetector Entry](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:buildSrc/src/main/kotlin/androidx/build/dependencyTracker/AffectedModuleDetector.kt;l=526;drc=cfb504756386b6225a2176d1d6efe2f55d4fa564) |
| 106 | |
| 107 | Note: Compose macrobenchmarks are generally duplicated with View system |
| 108 | counterparts, defined in `:benchmark:integration-tests:macrobenchmark-target`. |
| 109 | This is how we compare performance of the two systems. |