Don't remove a group from insertTable when copying it to the new group during applyChanges

The insertTable will be disposed and recreated after changes applied.

Motivation: removing a group requires moving the gap twice that implies copying the parts of the array. It seems that it's not necessary since the insert table can be cleaned up later all at once.

This change helps to run applyChanges faster in cases when we insert a lot of new items (~2-3 times improvement).

Test: ./gradlew :compose:runtime:runtime:testDebugUnitTest
Change-Id: Ia8e850d98a777822fc34f0159fbdcf0879c4ae22
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
index 319bccf..af9f3bc 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
@@ -1479,6 +1479,7 @@
     }
 
     internal fun changesApplied() {
+        createFreshInsertTable()
         providerUpdates.clear()
     }
 
@@ -3516,7 +3517,11 @@
             val insertTable = insertTable
             recordSlotEditingOperation { _, slots, _ ->
                 slots.beginInsert()
-                slots.moveFrom(insertTable, anchor.toIndexFor(insertTable))
+                slots.moveFrom(
+                    table = insertTable,
+                    index = anchor.toIndexFor(insertTable),
+                    removeSourceGroup = false
+                )
                 slots.endInsert()
             }
         } else {
@@ -3532,7 +3537,11 @@
                     }
                 }
                 slots.beginInsert()
-                slots.moveFrom(insertTable, anchor.toIndexFor(insertTable))
+                slots.moveFrom(
+                    table = insertTable,
+                    index = anchor.toIndexFor(insertTable),
+                    removeSourceGroup = false
+                )
                 slots.endInsert()
             }
         }
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SlotTable.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SlotTable.kt
index 3ed0e5a2..1a46dc9 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SlotTable.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SlotTable.kt
@@ -1949,7 +1949,8 @@
             fromIndex: Int,
             toWriter: SlotWriter,
             updateFromCursor: Boolean,
-            updateToCursor: Boolean
+            updateToCursor: Boolean,
+            removeSourceGroup: Boolean = true
         ): List<Anchor> {
             val groupsToMove = fromWriter.groupSize(fromIndex)
             val sourceGroupsEnd = fromIndex + groupsToMove
@@ -2057,7 +2058,11 @@
             } else emptyList()
 
             val parentGroup = fromWriter.parent(fromIndex)
-            val anchorsRemoved = if (updateFromCursor) {
+            val anchorsRemoved = if (!removeSourceGroup) {
+                // e.g.: we can skip groups removal for insertTable of Composer because
+                // it's going to be disposed anyway after changes applied
+                false
+            } else if (updateFromCursor) {
                 // Remove the group using the sequence the writer expects when removing a group, that
                 // is the root group and the group's parent group must be correctly started and ended
                 // when it is not a root group.
@@ -2164,7 +2169,7 @@
      *
      * @return a list of the anchors that were moved
      */
-    fun moveFrom(table: SlotTable, index: Int): List<Anchor> {
+    fun moveFrom(table: SlotTable, index: Int, removeSourceGroup: Boolean = true): List<Anchor> {
         runtimeCheck(insertCount > 0)
 
         if (index == 0 && currentGroup == 0 && this.table.groupsSize == 0) {
@@ -2196,7 +2201,8 @@
                 index,
                 this,
                 updateFromCursor = true,
-                updateToCursor = true
+                updateToCursor = true,
+                removeSourceGroup = removeSourceGroup
             )
         }
     }