[go: nahoru, domu]

Updated docs for ObjectList

Fixes: 299364273

Added doc to indicate when ObjectList should be used instead
of ArrayList.

Added a benchmark for ObjectList. This can be used to tune
the list in the future. Some comparisons between ObjectList
and ArrayList:

MutableObjectList:
   178   ns           0 allocs    addAll
   455   ns           0 allocs    add
   309   ns           0 allocs    get
   143   ns           0 allocs    forEach
26,809   ns           0 allocs    contains
 2,658   ns           0 allocs    removeStart
   406   ns           0 allocs    removeEnd

ArrayList:
   375   ns           1 allocs    addAll
   420   ns           0 allocs    add
   404   ns           0 allocs    get
   475   ns           1 allocs    forEach
21,351   ns           0 allocs    contains
 2,731   ns           1 allocs    removeStart
   510   ns           1 allocs    removeEnd

Test: just a benchmark
Change-Id: I26ea18028872d764ae6f224bacf247cec1fd80a5
diff --git a/collection/collection-benchmark/src/androidTest/java/androidx/collection/ObjectListBenchmarkTest.kt b/collection/collection-benchmark/src/androidTest/java/androidx/collection/ObjectListBenchmarkTest.kt
new file mode 100644
index 0000000..a6ba28f
--- /dev/null
+++ b/collection/collection-benchmark/src/androidTest/java/androidx/collection/ObjectListBenchmarkTest.kt
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2023 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.collection
+
+import androidx.benchmark.junit4.BenchmarkRule
+import androidx.benchmark.junit4.measureRepeated
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class ObjectListBenchmarkTest {
+    val ObjectCount = 100
+    private val list: ObjectList<String> = MutableObjectList<String>(ObjectCount).also { list ->
+        repeat(ObjectCount) {
+            list += it.toString()
+        }
+    }
+
+    private val array = Array(ObjectCount) { it.toString() }
+
+    @get:Rule
+    val benchmark = BenchmarkRule()
+
+    @Test
+    fun forEach() {
+        benchmark.measureRepeated {
+            @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE")
+            var last: String
+            list.forEach { element ->
+                last = element
+            }
+        }
+    }
+
+    @Test
+    fun add() {
+        val mutableList = MutableObjectList<String>(ObjectCount)
+        benchmark.measureRepeated {
+            repeat(ObjectCount) {
+                mutableList += array[it]
+            }
+            mutableList.clear()
+        }
+    }
+
+    @Test
+    fun contains() {
+        benchmark.measureRepeated {
+            repeat(ObjectCount) {
+                list.contains(array[it])
+            }
+        }
+    }
+
+    @Test
+    fun get() {
+        benchmark.measureRepeated {
+            repeat(ObjectCount) {
+                list[it]
+            }
+        }
+    }
+
+    @Test
+    fun addAll() {
+        val mutableList = MutableObjectList<String>(ObjectCount)
+        benchmark.measureRepeated {
+            mutableList += list
+            mutableList.clear()
+        }
+    }
+
+    @Test
+    fun removeStart() {
+        val mutableList = MutableObjectList<String>(ObjectCount)
+        benchmark.measureRepeated {
+            mutableList += list
+            repeat(ObjectCount) {
+                mutableList.removeAt(0)
+            }
+        }
+    }
+
+    @Test
+    fun removeEnd() {
+        val mutableList = MutableObjectList<String>(ObjectCount)
+        benchmark.measureRepeated {
+            mutableList += list
+            for (i in ObjectCount - 1 downTo 0) {
+                mutableList.removeAt(i)
+            }
+        }
+    }
+}
diff --git a/collection/collection/src/commonMain/kotlin/androidx/collection/ObjectList.kt b/collection/collection/src/commonMain/kotlin/androidx/collection/ObjectList.kt
index 105ebaf..12703b0 100644
--- a/collection/collection/src/commonMain/kotlin/androidx/collection/ObjectList.kt
+++ b/collection/collection/src/commonMain/kotlin/androidx/collection/ObjectList.kt
@@ -36,6 +36,11 @@
  * **Note** [List] access is available through [asList] when developers need access to the
  * common API.
  *
+ * It is best to use this for all internal implementations where a list of reference types
+ * is needed. Use [List] in public API to take advantage of the commonly-used interface.
+ * It is common to use [ObjectList] internally and use [asList] to get a [List] interface
+ * for interacting with public APIs.
+ *
  * @see MutableObjectList
  * @see FloatList
  * @see IntList
@@ -575,6 +580,11 @@
  * **Note** [MutableList] access is available through [asMutableList] when developers need
  * access to the common API.
  *
+ * It is best to use this for all internal implementations where a list of reference types
+ * is needed. Use [MutableList] in public API to take advantage of the commonly-used interface.
+ * It is common to use [MutableObjectList] internally and use [asMutableList] or [asList]
+ * to get a [MutableList] or [List] interface for interacting with public APIs.
+ *
  * @see ObjectList
  * @see MutableFloatList
  * @see MutableIntList