Skip to content
This repository has been archived by the owner on Nov 8, 2023. It is now read-only.

Commit

Permalink
Merge "Improve initial composition performance" into androidx-master-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
chuckjaz authored and Gerrit Code Review committed Jul 12, 2019
2 parents 848c2c6 + d9fc2ca commit 2c92cd8
Showing 1 changed file with 30 additions and 9 deletions.
39 changes: 30 additions & 9 deletions compose/compose-runtime/src/main/java/androidx/compose/Composer.kt
Expand Up @@ -321,10 +321,10 @@ open class Composer<N>(
// Deprecated
override fun <T : N> emitNode(factory: () -> T) {
if (inserting) {
// The previous pending is the pending information for where the node is being inserted.
// They must exist as we are in insert mode and entering inserting mode created them.
val insertIndex = nodeIndexStack.peek()
pending!!.nodeCount++
// The pending is the pending information for where the node is being inserted.
// pending will be null here when the parent was inserted too.
pending?.let { it.nodeCount++ }
groupNodeCount++
recordOperation { applier, slots, _ ->
val node = factory()
Expand All @@ -340,10 +340,9 @@ open class Composer<N>(
}

override fun <T : N> createNode(factory: () -> T) {
// The previous pending is the pending information for where the node is being inserted.
// They must exist as we are in insert mode and entering inserting mode created them.
val insertIndex = nodeIndexStack.peek()
pending!!.nodeCount++
// see emitNode
pending?.let { it.nodeCount++ }
groupNodeCount++
recordOperation { applier, slots, _ ->
val node = factory()
Expand All @@ -357,7 +356,8 @@ open class Composer<N>(
override fun emitNode(node: N) {
assert(inserting) { "emitNode() called when not inserting" }
val insertIndex = nodeIndexStack.peek()
pending!!.nodeCount++
// see emitNode
pending?.let { it.nodeCount++ }
groupNodeCount++
recordOperation { applier, slots, _ ->
slots.update(node)
Expand Down Expand Up @@ -598,6 +598,24 @@ open class Composer<N>(

private fun start(key: Any, action: SlotAction) {
assert(childrenAllowed) { "A call to createNode(), emitNode() or useNode() expected" }

// Check for the insert fast path. If we are already inserting (creating nodes) then
// there is no need to track insert, deletes and moves with a pending changes object.
if (inserting) {
slots.beginEmpty()
recordOperation { _, slots, _ ->
slots.update(key)
slots.start(action)
}
pending?.let { pending ->
val insertKeyInfo = KeyInfo(key, -1, 0, -1)
pending.registerInsert(insertKeyInfo, nodeIndex - pending.startIndex)
pending.recordUsed(insertKeyInfo)
}
enterGroup(action, null, null)
return
}

if (pending == null) {
val slotKey = slots.next()
if (slotKey == key) {
Expand Down Expand Up @@ -948,8 +966,11 @@ open class Composer<N>(
}

private fun invalidate(scope: RecomposeScope, sync: Boolean) {
val location = scope.anchor?.location(slotTable) ?: return
assert(location >= 0) { "Invalid anchor" }
val location = scope.anchor?.location(slotTable)
?: return // The scope never entered the composition
if (location < 0)
return // The scope was removed from the composition

invalidations.insertIfMissing(location, scope)
if (isComposing && location > slots.current) {
// if we are invalidating a scope that is going to be traversed during this
Expand Down

0 comments on commit 2c92cd8

Please sign in to comment.