blob: 86d0536ef3591f4c2dd3d517fb2e2a24b079d6b9 [file] [log] [blame] [view]
AndroidX Core Team0e7745f2021-04-08 17:00:10 +00001# 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>
AndroidX Core Team4cc85fa2021-11-23 15:58:34 +000021 <td>Slow iteration speed (Often more than a minute)</td>
AndroidX Core Team0e7745f2021-04-08 17:00:10 +000022 <td>Fast iteration speed (Often less than 10 seconds)</td>
23 </tr>
24 <tr>
25 <td>Results come with profiling traces</td>
AndroidX Core Team4cc85fa2021-11-23 15:58:34 +000026 <td>Optional stack sampling/method tracing</td>
AndroidX Core Team0e7745f2021-04-08 17:00:10 +000027 </tr>
28 <tr>
AndroidX Core Team4cc85fa2021-11-23 15:58:34 +000029 <td>Min API 23</td>
AndroidX Core Team0e7745f2021-04-08 17:00:10 +000030 <td>Min API 14</td>
31 </tr>
32</table>
33
34The
AndroidX Core Team9bd4c782021-05-19 14:20:12 -070035[public documentation](https://developer.android.com/studio/profile/macrobenchmark)
AndroidX Core Team0e7745f2021-04-08 17:00:10 +000036for macrobenchmark explains how to use the library. This page focuses on
37specifics to writing library macrobenchmarks in the AndroidX repo. If you're
38looking for measuring CPU perf of individual functions, see the guide for
AndroidX Core Team5fa61982023-01-13 10:43:41 -050039MICRObenchmarks [here](/company/teams/androidx/benchmarking.md).
AndroidX Core Team0e7745f2021-04-08 17:00:10 +000040
41### Writing the benchmark
42
43Benchmarks 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)
45provided by the library:
46
47<section class="tabs">
48
49#### Kotlin {.new-tab}
50
51```kotlin
AndroidX Core Team0e7745f2021-04-08 17:00:10 +000052 @get:Rule
53 val benchmarkRule = MacrobenchmarkRule()
54
55 @Test
56 fun startup() = benchmarkRule.measureRepeated(
57 packageName = "mypackage.myapp",
58 metrics = listOf(StartupTimingMetric()),
59 startupMode = StartupMode.COLD,
60 iterations = 5
61 ) { // this = MacrobenchmarkScope
62 pressHome()
63 val intent = Intent()
64 intent.setPackage("mypackage.myapp")
65 intent.setAction("mypackage.myapp.myaction")
66 startActivityAndWait(intent)
67 }
AndroidX Core Team0e7745f2021-04-08 17:00:10 +000068```
69
70#### Java {.new-tab}
71
72```java
AndroidX Core Team4cc85fa2021-11-23 15:58:34 +000073 @Rule
74 public MacrobenchmarkRule mBenchmarkRule = MacrobenchmarkRule()
75
76 @Test
77 public void startup() {
78 mBenchmarkRule.measureRepeated(
79 "mypackage.myapp",
80 Collections.singletonList(new StartupTimingMetric()),
81 StartupMode.COLD,
82 /* iterations = */ 5,
83 scope -> {
84 scope.pressHome();
85 Intent intent = Intent();
86 intent.setPackage("mypackage.myapp");
87 intent.setAction("mypackage.myapp.myaction");
88 scope.startActivityAndWait(intent);
89 return Unit.INSTANCE;
90 }
91 );
92 }
AndroidX Core Team0e7745f2021-04-08 17:00:10 +000093```
94
95</section>
96
97## Project structure
98
99As in the public documentation, macrobenchmarks in the AndroidX repo are
100comprised of an app, and a separate macrobenchmark module. Additional setups
101steps/constraints for the AndroidX repository are listed below.
102
1031. App and macrobenchmark modules must be unique, and map 1:1.
104
1051. Target app path in `settings.gradle` must end with
106 `:integration-tests:macrobenchmark-target`.
107
1081. Macrobenchmark library path must be at the same path, but instead ending
109 with `:integration-tests:macrobenchmark`
110
1111. An entry should be placed in AffectedModuleDetector to recognize
112 macrobenchmark dependency on target app module,
113 [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)
114
115Compose Macrobenchmark Examples:
116
117* [`:compose:integration-tests:macrobenchmark-target`](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/integration-tests/macrobenchmark-target/)
118
119* [`:compose:integration-tests:macrobenchmark`](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/integration-tests/macrobenchmark/)
120
121* [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)
122
123Note: Compose macrobenchmarks are generally duplicated with View system
124counterparts, defined in `:benchmark:integration-tests:macrobenchmark-target`.
125This is how we compare performance of the two systems.
AndroidX Core Team6146a742022-09-26 09:45:06 -0700126
127### Setup checklist
128
129<table>
130 <tr>
131 <td><strong>Did you setup...</strong></td>
132 <td><strong>Required setup</strong></td>
133 </tr>
134 <tr>
135 <td>Two modules in settings.gradle</td>
136 <td>Both the macrobenchmark and target must be defined in sibling
137 modules</td>
138 </tr>
139 <tr>
140 <td>The module name for the benchmark (test) module</td>
141 <td>It must match /.*:integration-tests:.*macrobenchmark/</td>
142 </tr>
143 <tr>
144 <td>The module name for the target (integration app) module</td>
145 <td>It must match /.*:integration-tests:.*macrobenchmark-target</td>
146 </tr>
147 <tr>
148 <td>Register the modules in AffectedModuleDetector.kt</td>
149 <td>It must link the modules (see docs above)</td>
150 </tr>
151 <tr>
152 <td>Name the test class in a discoverable way</td>
153 <td>Test classes should have standalone names for easy discovery in the
154 web UI. E.g EmojiStartupTest instead of StartupTest.</td>
155 </tr>
156</table>