Skip to content

Commit 7bbb443

Browse files
committed
Reduce AccelerateHeavyScreenBenchmark variance
- Increased iterations from 1 to 10 for more realistic results, in line with the spirit of the performance codelab. - Updated the measure block to only include frames from scrolling, removing: 1) frames from the cold startup of the activity and 2) frames from the initial faked load delay of 500 ms. - Added a warmup iteration that triggers loading of images. - The 500 ms wait wasn't enough for the drag to settle, so we were potentially starting the second drag before the first had settled, and then ending the measure too early. Bumped the wait to 1000 ms, traces now show a clear ~200 ms gaps with no frames.
1 parent 6fe60cd commit 7bbb443

File tree

2 files changed

+56
-31
lines changed

2 files changed

+56
-31
lines changed

PerformanceCodelab/measure/src/main/java/com/compose/performance/measure/AbstractBenchmark.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ import androidx.benchmark.macro.junit4.MacrobenchmarkRule
2323
import org.junit.Rule
2424

2525
abstract class AbstractBenchmark(
26-
protected val startupMode: StartupMode = StartupMode.WARM,
27-
// For the purpose of this workshop, we have iterations set to low number.
28-
// For more accurate measurements, you should increase the iterations to at least 10
29-
// based on how much variance occurs in the results. In general more iterations = more stable
30-
// results, but longer execution time.
26+
protected val startupMode: StartupMode? = StartupMode.WARM,
27+
// For accurate measurements, you should set the iterations to at least 10, based on how much
28+
// variance occurs in the results. In general more iterations = more stable
29+
// results, but longer execution time. For exploration purposes you could set
30+
// iterations to 1.
3131
protected val iterations: Int = 1
3232
) {
3333
@get:Rule

PerformanceCodelab/measure/src/main/java/com/compose/performance/measure/AccelerateHeavyScreenBenchmark.kt

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,42 +21,67 @@ import androidx.benchmark.macro.ExperimentalMetricApi
2121
import androidx.benchmark.macro.FrameTimingMetric
2222
import androidx.benchmark.macro.MacrobenchmarkScope
2323
import androidx.benchmark.macro.Metric
24-
import androidx.benchmark.macro.StartupMode
2524
import androidx.benchmark.macro.TraceSectionMetric
2625
import androidx.test.ext.junit.runners.AndroidJUnit4
2726
import androidx.test.filters.LargeTest
2827
import androidx.test.uiautomator.By
28+
import androidx.test.uiautomator.BySelector
2929
import androidx.test.uiautomator.Until
3030
import org.junit.Test
3131
import org.junit.runner.RunWith
3232

3333
@LargeTest
3434
@RunWith(AndroidJUnit4::class)
3535
@OptIn(ExperimentalMetricApi::class)
36-
class AccelerateHeavyScreenBenchmark : AbstractBenchmark(StartupMode.COLD) {
37-
38-
@Test
39-
fun accelerateHeavyScreenCompilationFull() = benchmark(CompilationMode.Full())
40-
41-
override val metrics: List<Metric> =
42-
listOf(
43-
FrameTimingMetric(),
44-
TraceSectionMetric("ImagePlaceholder", TraceSectionMetric.Mode.Sum),
45-
TraceSectionMetric("PublishDate.registerReceiver", TraceSectionMetric.Mode.Sum),
46-
TraceSectionMetric("ItemTag", TraceSectionMetric.Mode.Sum)
47-
)
48-
49-
override fun MacrobenchmarkScope.measureBlock() {
50-
pressHome()
51-
startTaskActivity("accelerate_heavy")
52-
53-
device.wait(Until.hasObject(By.res("list_of_items")), 5_000)
54-
val feed = device.findObject(By.res("list_of_items"))
55-
feed.setGestureMargin(device.displayWidth / 5)
56-
57-
repeat(2) {
58-
feed.drag(Point(feed.visibleCenter.x, feed.visibleBounds.top))
59-
Thread.sleep(500)
60-
}
36+
class AccelerateHeavyScreenBenchmark : AbstractBenchmark(
37+
// This benchmark tests scrolling from an already started activity in the setup phase, we don't
38+
// want the activity to be started in the measure phase.
39+
startupMode = null,
40+
iterations = 10
41+
) {
42+
43+
@Test
44+
fun accelerateHeavyScreenCompilationFull() = benchmark(CompilationMode.Full())
45+
46+
override val metrics: List<Metric> =
47+
listOf(
48+
FrameTimingMetric(),
49+
TraceSectionMetric("ImagePlaceholder", TraceSectionMetric.Mode.Sum),
50+
TraceSectionMetric("PublishDate.registerReceiver", TraceSectionMetric.Mode.Sum),
51+
TraceSectionMetric("ItemTag", TraceSectionMetric.Mode.Sum)
52+
)
53+
54+
private var isFirstSetup = true
55+
56+
override fun MacrobenchmarkScope.setupBlock() {
57+
if (isFirstSetup) {
58+
isFirstSetup = false
59+
startActivity()
60+
// Perform a warmup round that will trigger the initial loading of images to avoid having
61+
// a first iteration that's significantly slower than other iterations
62+
measureBlock()
63+
}
64+
finishActivity()
65+
startActivity()
66+
}
67+
68+
private fun MacrobenchmarkScope.startActivity() {
69+
startTaskActivity("accelerate_heavy")
70+
device.wait(Until.hasObject(By.res("list_of_items")), 5_000)
71+
}
72+
73+
private fun MacrobenchmarkScope.finishActivity() {
74+
device.pressBack()
75+
device.wait(Until.gone(By.res("list_of_items")), 2_000)
76+
}
77+
78+
override fun MacrobenchmarkScope.measureBlock() {
79+
val feed = device.findObject(By.res("list_of_items"))
80+
81+
repeat(2) {
82+
feed.drag(Point(feed.visibleCenter.x, feed.visibleBounds.top))
83+
// Enough time for scroll to settle.
84+
Thread.sleep(1000)
6185
}
86+
}
6287
}

0 commit comments

Comments
 (0)