From 687974c0bcd73c2906a746d9c17a96e66de6047c Mon Sep 17 00:00:00 2001 From: Jake Wharton Date: Wed, 25 Sep 2024 23:45:02 -0400 Subject: [PATCH] Collapse surface arrays into a single contiguous chunk (#485) Better locality in memory. --- .../kotlin/com/jakewharton/mosaic/canvas.kt | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/canvas.kt b/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/canvas.kt index 4151b1e7..f9532655 100644 --- a/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/canvas.kt +++ b/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/canvas.kt @@ -35,18 +35,26 @@ internal class TextSurface( override var translationX = 0 override var translationY = 0 - private val rows = Array(height) { Array(width) { TextPixel(' ') } } + private val cells = Array(width * height) { TextPixel(' ') } - override operator fun get(row: Int, column: Int) = rows[translationY + row][translationX + column] + override operator fun get(row: Int, column: Int): TextPixel { + val x = translationX + column + val y = row + translationY + check(x in 0 until width) + check(y in 0 until height) + return cells[y * width + x] + } fun appendRowTo(appendable: Appendable, row: Int) { // Reused heap allocation for building ANSI attributes inside the loop. val attributes = mutableIntListOf() - val rowPixels = rows[row] var lastPixel = blankPixel - for (columnIndex in 0 until width) { - val pixel = rowPixels[columnIndex] + + val rowStart = row * width + val rowStop = rowStart + width + for (columnIndex in rowStart until rowStop) { + val pixel = cells[columnIndex] if (ansiLevel != AnsiLevel.NONE) { if (pixel.foreground != lastPixel.foreground) {