Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@
## 2024-05-10 - Optimize Math Operations with Lookup Tables
**Learning:** When mathematical operations depend strictly on a small, discrete domain (e.g., converting 8-bit color components 0..255 from sRGB to linear space), utilizing pre-computed arrays or lookup tables instead of redundant on-the-fly computation (divisions, conditionals, `.pow()`) significantly improves performance in hot paths (over 20x improvement).
**Action:** Identify finite input domains in hot paths and pre-calculate their results into arrays (like `DoubleArray(256)`) instead of doing continuous computations repeatedly.

## 2024-06-25 - Local variable caching for array lookups in math hotpaths
**Learning:** In highly mathematical operations (like `matrixMultiply` in `halogen-core`), caching repeated array lookups (e.g. `row[0]`, `matrix[0]`) into local variables noticeably reduces the overhead of bounds-checking and pointer deference.
**Action:** Unroll fixed-size vector and matrix array accesses into local variables.
16 changes: 13 additions & 3 deletions halogen-core/src/commonMain/kotlin/halogen/color/MathUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,19 @@ internal object MathUtils {
180.0 - abs(abs(a - b) - 180.0)

fun matrixMultiply(row: DoubleArray, matrix: Array<DoubleArray>): DoubleArray {
val a = row[0] * matrix[0][0] + row[1] * matrix[0][1] + row[2] * matrix[0][2]
val b = row[0] * matrix[1][0] + row[1] * matrix[1][1] + row[2] * matrix[1][2]
val c = row[0] * matrix[2][0] + row[1] * matrix[2][1] + row[2] * matrix[2][2]
// Cache array elements in local variables to avoid redundant array bounds checking and
// pointer dereferencing in hot paths.
val r0 = row[0]
val r1 = row[1]
val r2 = row[2]

val m0 = matrix[0]
val m1 = matrix[1]
val m2 = matrix[2]

val a = r0 * m0[0] + r1 * m0[1] + r2 * m0[2]
val b = r0 * m1[0] + r1 * m1[1] + r2 * m1[2]
val c = r0 * m2[0] + r1 * m2[1] + r2 * m2[2]
return doubleArrayOf(a, b, c)
}
}
Loading