[KT-57607] Fix performance of ArrayList.addAll methods in JS stdlib (#5116)

* Fix performance of ArrayList.addAll methods in JS stdlib: extend the backing array and copy elements manually
* Update expected reachable nodes after DCE in test data

---------

Co-authored-by: Ilya Gorbunov <ilya.gorbunov@jetbrains.com>
This commit is contained in:
deotime
2023-04-05 13:18:11 -05:00
committed by GitHub
parent 11b7fe2c4a
commit 7aaba3b78a
2 changed files with 18 additions and 6 deletions
@@ -1,6 +1,6 @@
// IGNORE_FIR // IGNORE_FIR
// KJS_WITH_FULL_RUNTIME // KJS_WITH_FULL_RUNTIME
// EXPECTED_REACHABLE_NODES: 1819 // EXPECTED_REACHABLE_NODES: 2002
// MODULE: lib1 // MODULE: lib1
// FILE: lib1.kt // FILE: lib1.kt
package lib1 package lib1
@@ -67,11 +67,20 @@ public actual open class ArrayList<E> internal constructor(private var array: Ar
modCount++ modCount++
} }
private fun increaseLength(amount: Int): Int {
val previous = size
array.asDynamic().length = size + amount
return previous
}
actual override fun addAll(elements: Collection<E>): Boolean { actual override fun addAll(elements: Collection<E>): Boolean {
checkIsMutable() checkIsMutable()
if (elements.isEmpty()) return false if (elements.isEmpty()) return false
array += elements.toTypedArray<Any?>() val offset = increaseLength(elements.size)
elements.forEachIndexed { index, element ->
array[offset + index] = element
}
modCount++ modCount++
return true return true
} }
@@ -82,10 +91,13 @@ public actual open class ArrayList<E> internal constructor(private var array: Ar
if (index == size) return addAll(elements) if (index == size) return addAll(elements)
if (elements.isEmpty()) return false if (elements.isEmpty()) return false
when (index) {
size -> return addAll(elements) val tail = array.asDynamic().splice(index).unsafeCast<Array<E>>()
0 -> array = elements.toTypedArray<Any?>() + array addAll(elements)
else -> array = array.copyOfRange(0, index).asDynamic().concat(elements.toTypedArray<Any?>(), array.copyOfRange(index, size))
val offset = increaseLength(tail.size)
repeat(tail.size) { tailIndex ->
array[offset + tailIndex] = tail[tailIndex]
} }
modCount++ modCount++