diff --git a/.jules/bolt.md b/.jules/bolt.md index 4596c40..5897863 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -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. diff --git a/halogen-core/src/commonMain/kotlin/halogen/color/MathUtils.kt b/halogen-core/src/commonMain/kotlin/halogen/color/MathUtils.kt index 0aa82c8..92caf01 100644 --- a/halogen-core/src/commonMain/kotlin/halogen/color/MathUtils.kt +++ b/halogen-core/src/commonMain/kotlin/halogen/color/MathUtils.kt @@ -62,9 +62,19 @@ internal object MathUtils { 180.0 - abs(abs(a - b) - 180.0) fun matrixMultiply(row: DoubleArray, matrix: Array): 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) } }