Add SLC benchmark to M3 benchmarks and refactor TLC benchmark.
Add ScalingLazyColumnBenchmark macrobenchmark to Material3
macrobenchmark, and refactor both TLC and SLC benchmarks to use
device.swipe() instead of list.drag(). The change makes it easier to
compare SLC, TLC and Picker Benchmarks.
Also increased number of swipes in the list/picker benchmarks from 4 to
20, for bigger sample size and more reliable results.
The results for benchmark runs are attached in the bug.
Bug: 389878201
Test: Update benchmark tests
Change-Id: I6bad9e993e6ef9316fc6d129af0388d28cb386a6
diff --git a/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/DatePickerBenchmark.kt b/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/DatePickerBenchmark.kt
index 51431d0..fe612b2 100644
--- a/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/DatePickerBenchmark.kt
+++ b/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/DatePickerBenchmark.kt
@@ -84,13 +84,8 @@
device.waitForIdle()
SystemClock.sleep(500)
repeat(3) { columnIndex ->
- repeat(2) { i ->
- val endY =
- if (i % 2 == 0) {
- device.displayHeight / 10 // scroll up
- } else {
- device.displayHeight * 9 / 10 // scroll down
- }
+ repeat(20) {
+ val endY = device.displayHeight * 9 / 10 // scroll down
device.swipe(
device.displayWidth / 2,
device.displayHeight / 2,
diff --git a/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/PickerBenchmark.kt b/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/PickerBenchmark.kt
index 280b461..5e89683 100644
--- a/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/PickerBenchmark.kt
+++ b/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/PickerBenchmark.kt
@@ -45,13 +45,8 @@
override val exercise: MacrobenchmarkScope.() -> Unit
get() = {
- repeat(4) { i ->
- val endY =
- if (i % 2 == 0) {
- device.displayHeight / 10 // scroll up
- } else {
- device.displayHeight * 9 / 10 // scroll down
- }
+ repeat(20) {
+ val endY = device.displayHeight * 9 / 10 // scroll down
device.swipe(
device.displayWidth / 2,
device.displayHeight / 2,
diff --git a/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/ScalingLazyColumnBenchmark.kt b/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/ScalingLazyColumnBenchmark.kt
new file mode 100644
index 0000000..37f0dab
--- /dev/null
+++ b/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/ScalingLazyColumnBenchmark.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package androidx.wear.compose.material3.macrobenchmark.common
+
+import android.os.SystemClock
+import androidx.benchmark.macro.MacrobenchmarkScope
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.BoxScope
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.unit.dp
+import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
+import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
+import androidx.wear.compose.material3.AppScaffold
+import androidx.wear.compose.material3.EdgeButton
+import androidx.wear.compose.material3.MaterialTheme
+import androidx.wear.compose.material3.ScreenScaffold
+import androidx.wear.compose.material3.Text
+import kotlinx.coroutines.launch
+
+val ScalingLazyColumnBenchmark =
+ object : MacrobenchmarkScreen {
+ override val content: @Composable (BoxScope.() -> Unit)
+ get() = {
+ val state = rememberScalingLazyListState()
+ val coroutineScope = rememberCoroutineScope()
+ AppScaffold {
+ ScreenScaffold(
+ state,
+ contentPadding = PaddingValues(horizontal = 10.dp, vertical = 20.dp),
+ edgeButton = {
+ EdgeButton(
+ onClick = { coroutineScope.launch { state.scrollToItem(1) } }
+ ) {
+ Text("To top")
+ }
+ }
+ ) { contentPadding ->
+ ScalingLazyColumn(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ contentPadding = contentPadding,
+ state = state,
+ modifier =
+ Modifier.background(MaterialTheme.colorScheme.background)
+ .semantics { contentDescription = CONTENT_DESCRIPTION }
+ ) {
+ items(5000) {
+ Text(
+ "Item $it",
+ color = MaterialTheme.colorScheme.onSurface,
+ style = MaterialTheme.typography.bodyLarge,
+ modifier = Modifier.fillMaxWidth().padding(10.dp)
+ )
+ }
+ }
+ }
+ }
+ }
+
+ override val exercise: MacrobenchmarkScope.() -> Unit
+ get() = {
+ repeat(20) {
+ val endY = device.displayHeight * 9 / 10 // scroll down
+
+ device.swipe(
+ device.displayWidth / 2,
+ device.displayHeight / 2,
+ device.displayWidth / 2,
+ endY,
+ 10
+ )
+ device.waitForIdle()
+ SystemClock.sleep(500)
+ }
+ }
+ }
diff --git a/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/TimePickerBenchmark.kt b/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/TimePickerBenchmark.kt
index 7d15ce7..aad5c48 100644
--- a/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/TimePickerBenchmark.kt
+++ b/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/TimePickerBenchmark.kt
@@ -39,14 +39,9 @@
override val exercise: MacrobenchmarkScope.() -> Unit
get() = {
- repeat(4) { i ->
+ repeat(20) {
val startY = device.displayHeight / 2
- val endY =
- if (i % 2 == 0) {
- device.displayHeight / 10 // scroll up
- } else {
- device.displayHeight * 9 / 10 // scroll down
- }
+ val endY = device.displayHeight * 9 / 10 // scroll down
val hourX = device.displayWidth / 4
device.swipe(hourX, startY, hourX, endY, 10)
diff --git a/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/TransformingLazyColumnBenchmark.kt b/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/TransformingLazyColumnBenchmark.kt
index bc24b82..dae1ab0 100644
--- a/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/TransformingLazyColumnBenchmark.kt
+++ b/wear/compose/compose-material3/macrobenchmark-common/src/main/java/androidx/wear/compose/material3/macrobenchmark/common/TransformingLazyColumnBenchmark.kt
@@ -16,7 +16,7 @@
package androidx.wear.compose.material3.macrobenchmark.common
-import android.graphics.Point
+import android.os.SystemClock
import androidx.benchmark.macro.MacrobenchmarkScope
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.BoxScope
@@ -29,7 +29,6 @@
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
-import androidx.test.uiautomator.By
import androidx.wear.compose.foundation.lazy.TransformingLazyColumn
import androidx.wear.compose.foundation.lazy.rememberTransformingLazyColumnState
import androidx.wear.compose.material3.AppScaffold
@@ -89,12 +88,17 @@
override val exercise: MacrobenchmarkScope.() -> Unit
get() = {
- val list = device.findObject(By.desc(CONTENT_DESCRIPTION))
- // Setting a gesture margin is important otherwise gesture nav is triggered.
- list.setGestureMargin(device.displayWidth / 5)
- repeat(5) {
- list.drag(Point(list.visibleCenter.x, list.visibleCenter.y / 3))
+ repeat(20) {
+ val endY = device.displayHeight * 9 / 10 // scroll down
+ device.swipe(
+ device.displayWidth / 2,
+ device.displayHeight / 2,
+ device.displayWidth / 2,
+ endY,
+ 10
+ )
device.waitForIdle()
+ SystemClock.sleep(500)
}
}
}
diff --git a/wear/compose/compose-material3/macrobenchmark-target/src/main/AndroidManifest.xml b/wear/compose/compose-material3/macrobenchmark-target/src/main/AndroidManifest.xml
index 6ec1884..0127c6d 100644
--- a/wear/compose/compose-material3/macrobenchmark-target/src/main/AndroidManifest.xml
+++ b/wear/compose/compose-material3/macrobenchmark-target/src/main/AndroidManifest.xml
@@ -225,6 +225,17 @@
</activity>
<activity
+ android:name=".ScalingLazyColumnActivity"
+ android:theme="@style/AppTheme"
+ android:exported="true">
+ <intent-filter>
+ <action android:name=
+ "androidx.wear.compose.material3.macrobenchmark.target.SCALING_LAZY_COLUMN_ACTIVITY" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <activity
android:name=".SliderActivity"
android:theme="@style/AppTheme"
android:exported="true">
diff --git a/wear/compose/compose-material3/macrobenchmark-target/src/main/java/androidx/wear/compose/material3/macrobenchmark/target/ScalingLazyColumnActivity.kt b/wear/compose/compose-material3/macrobenchmark-target/src/main/java/androidx/wear/compose/material3/macrobenchmark/target/ScalingLazyColumnActivity.kt
new file mode 100644
index 0000000..0fafcad
--- /dev/null
+++ b/wear/compose/compose-material3/macrobenchmark-target/src/main/java/androidx/wear/compose/material3/macrobenchmark/target/ScalingLazyColumnActivity.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package androidx.wear.compose.material3.macrobenchmark.target
+
+import androidx.wear.compose.material3.macrobenchmark.common.ScalingLazyColumnBenchmark
+
+class ScalingLazyColumnActivity : BenchmarkBaseActivity(ScalingLazyColumnBenchmark)
diff --git a/wear/compose/compose-material3/macrobenchmark/src/main/java/androidx/wear/compose/material3/macrobenchmark/ScalingLazyColumnBenchmarkTest.kt b/wear/compose/compose-material3/macrobenchmark/src/main/java/androidx/wear/compose/material3/macrobenchmark/ScalingLazyColumnBenchmarkTest.kt
new file mode 100644
index 0000000..d3b0172
--- /dev/null
+++ b/wear/compose/compose-material3/macrobenchmark/src/main/java/androidx/wear/compose/material3/macrobenchmark/ScalingLazyColumnBenchmarkTest.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package androidx.wear.compose.material3.macrobenchmark
+
+import androidx.benchmark.macro.CompilationMode
+import androidx.test.filters.LargeTest
+import androidx.wear.compose.material3.macrobenchmark.common.ScalingLazyColumnBenchmark
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+@LargeTest
+@RunWith(Parameterized::class)
+class ScalingLazyColumnBenchmarkTest(compilationMode: CompilationMode) :
+ BenchmarkTestBase(
+ compilationMode = compilationMode,
+ macrobenchmarkScreen = ScalingLazyColumnBenchmark,
+ actionSuffix = "SCALING_LAZY_COLUMN_ACTIVITY"
+ )