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
3 changes: 3 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 2024-05-18 - Manual parsing avoids allocations
**Learning:** In Kotlin hot paths, replacing standard library string manipulations (`substring`, `toLong(16)`, `toString(16)`, `padStart`, `uppercase`) with explicit manual character array manipulation avoids intermediate `String` object allocations and measurably improves performance, especially when parsing small fixed-format structures like hex color strings used frequently in theme generation.
**Action:** Always prefer manual parsing logic that constructs from primitive character arrays or strings directly, instead of using fluent sequence of `String` conversion methods in hot paths like core algorithms.
23 changes: 20 additions & 3 deletions halogen-core/src/commonMain/kotlin/halogen/ThemeExpander.kt
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,33 @@ public object ThemeExpander {
require(hex.startsWith("#") && hex.length == 7) {
"Invalid hex color: \"$hex\". Expected format: #RRGGBB"
}
val rgb = hex.substring(1).toLong(16).toInt()
var rgb = 0
for (i in 1..6) {
val c = hex[i]
val digit = when {
c in '0'..'9' -> c - '0'
c in 'A'..'F' -> c - 'A' + 10
c in 'a'..'f' -> c - 'a' + 10
else -> throw IllegalArgumentException("Invalid hex color: \"$hex\". Expected format: #RRGGBB")
}
rgb = (rgb shl 4) or digit
}
return rgb or (0xFF shl 24).toInt()
}

/**
* Convert an ARGB integer to a hex color string like "#1A73E8".
*/
public fun argbToHex(argb: Int): String {
val rgb = argb and 0xFFFFFF
return "#" + rgb.toString(16).padStart(6, '0').uppercase()
val chars = CharArray(7)
chars[0] = '#'
var rgb = argb and 0xFFFFFF
for (i in 6 downTo 1) {
val nibble = rgb and 0xF
chars[i] = if (nibble < 10) (nibble + '0'.code).toChar() else (nibble - 10 + 'A'.code).toChar()
rgb = rgb shr 4
}
return chars.concatToString()
}

private fun buildScheme(palette: HalogenPalette, isDark: Boolean): HalogenColorScheme {
Expand Down
Loading