Skip to content

Commit b168065

Browse files
authored
ParagraphBuilder loops performance optimization (JetBrains#2638)
Replace all loops to use index-based loops to avoid allocating an Iterator object on each paragraph build. for (item in collection) allocates an iterator under the hood. Small change so no Youtrack issue linked (if necessary, can be done) ## Testing N/A ## Release Notes N/A
1 parent 47af63a commit b168065

1 file changed

Lines changed: 8 additions & 7 deletions

File tree

compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/platform/ParagraphBuilder.skiko.kt

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ import androidx.compose.ui.unit.TextUnit
5858
import androidx.compose.ui.unit.isSpecified
5959
import androidx.compose.ui.unit.isUnspecified
6060
import androidx.compose.ui.unit.sp
61+
import androidx.compose.ui.util.fastForEach
62+
import androidx.compose.ui.util.fastForEachReversed
6163
import kotlin.jvm.JvmMultifileClass
6264
import kotlin.jvm.JvmName
6365
import org.jetbrains.skia.Font as SkFont
@@ -419,7 +421,7 @@ internal class ParagraphBuilder(
419421

420422
var addText = true
421423

422-
for (op in ops) {
424+
ops.fastForEach { op ->
423425
if (addText && pos < op.position) {
424426
pb.addText(text.subSequence(pos, op.position).toString())
425427
}
@@ -513,24 +515,23 @@ internal class ParagraphBuilder(
513515
placeholders: List<AnnotatedString.Range<Placeholder>>
514516
): List<Op> {
515517
val cuts = mutableListOf<Cut>()
516-
for (annotation in annotations) {
517-
518+
annotations.fastForEach { annotation ->
518519
// TODO https://youtrack.jetbrains.com/issue/CMP-7151
519-
if (annotation.item !is SpanStyle) continue
520+
if (annotation.item !is SpanStyle) return@fastForEach
520521

521522
cuts.add(Cut.StyleAdd(annotation.start, annotation.item))
522523
cuts.add(Cut.StyleRemove(annotation.end, annotation.item))
523524
}
524525

525-
for (placeholder in placeholders) {
526+
placeholders.fastForEach { placeholder ->
526527
cuts.add(Cut.PutPlaceholder(placeholder.start, placeholder.item))
527528
cuts.add(Cut.EndPlaceholder(placeholder.end))
528529
}
529530

530531
val ops = mutableListOf<Op>(Op.StyleAdd(0, defaultStyle.toMutable()))
531532
cuts.sortBy { it.position }
532533
val activeStyles = mutableListOf(initialStyle)
533-
for (cut in cuts) {
534+
cuts.fastForEach { cut ->
534535
when (cut) {
535536
is Cut.StyleAdd -> {
536537
activeStyles.add(cut.style)
@@ -588,7 +589,7 @@ internal class ParagraphBuilder(
588589
}
589590

590591
private fun previousStyleAddAtTheSamePosition(position: Int, ops: List<Op>): Op.StyleAdd? {
591-
for (prevOp in ops.asReversed()) {
592+
ops.fastForEachReversed { prevOp ->
592593
if (prevOp.position < position) return null
593594
if (prevOp is Op.StyleAdd) return prevOp
594595
}

0 commit comments

Comments
 (0)