Optimize collection creation in Navigation.kt (#180)

* ⚡ Optimize collection creation in Navigation.kt

Replaced uses of `.map { ... }.toSet()` with `.mapTo(mutableSetOf()) { ... }` in Navigation.kt. This avoids the creation of intermediate ArrayList objects, saving unnecessary memory allocations.

* ⚡ Optimize collection creation in Navigation.kt

Replaced uses of `.map { ... }.toSet()` with `.mapTo(mutableSetOf()) { ... }` in Navigation.kt. This avoids the creation of intermediate ArrayList objects, saving unnecessary memory allocations. Fixed ktlint formatting issues causing CI failure.
This commit is contained in:
M57 authored and GitHub committed 2026-06-20 23:44:39 +03:00
1 parent 81b2ff3aa5
commit 045932ca8b
6 files changed
+71 -13

No files matched your search

@@ -177,7 +177,7 @@ private val DRAWER_ENTRIES =
DrawerEntry(AchievementsScreen, "Achievements", Icons.Filled.Info, DrawerSection.INSPECT),
)
private val DRAWER_GESTURE_SCREENS: Set<NavKey> = ALL_NAV_ITEMS.map { it.key }.toSet()
private val DRAWER_GESTURE_SCREENS: Set<NavKey> = ALL_NAV_ITEMS.mapTo(mutableSetOf()) { it.key }
@Composable
fun MainNavigation(sessionId: String? = null) {
@@ -29,8 +29,7 @@ abstract class HermesDatabase : RoomDatabase() {
if (BuildConfig.DEBUG) {
fallbackToDestructiveMigration(false)
}
}
.build()
}.build()
.also { instance = it }
}
@@ -812,12 +812,11 @@ private fun RichText(
}
private val TIMESTAMP_FORMATTER =
DateTimeFormatter.ofPattern("HH:mm")
DateTimeFormatter
.ofPattern("HH:mm")
.withZone(ZoneId.systemDefault())
private fun formatTimestamp(timestamp: Long): String {
return TIMESTAMP_FORMATTER.format(Instant.ofEpochMilli(timestamp))
}
private fun formatTimestamp(timestamp: Long): String = TIMESTAMP_FORMATTER.format(Instant.ofEpochMilli(timestamp))
/**
* Build an AnnotatedString with search matches highlighted.
@@ -19,7 +19,10 @@ object CronExpressionFormatter {
// 1. Check for common simple shortcuts
// Every X minutes: */X * * * *
if (minutePart.startsWith("*/") && hourPart == "*" && domPart == "*" && monthPart == "*" &&
if (minutePart.startsWith("*/") &&
hourPart == "*" &&
domPart == "*" &&
monthPart == "*" &&
dowPart == "*"
) {
val step = minutePart.substring(2).toIntOrNull()
@@ -27,7 +30,10 @@ object CronExpressionFormatter {
}
// Every X hours: 0 */X * * *
if (minutePart == "0" && hourPart.startsWith("*/") && domPart == "*" && monthPart == "*" &&
if (minutePart == "0" &&
hourPart.startsWith("*/") &&
domPart == "*" &&
monthPart == "*" &&
dowPart == "*"
) {
val step = hourPart.substring(2).toIntOrNull()
@@ -425,10 +425,26 @@ class E2eIntegrationTest {
assertFalse(viewModel.uiState.value.isLoading)
assertEquals(1, viewModel.uiState.value.sessions.size)
assertEquals("session-123", viewModel.uiState.value.sessions[0].id)
assertEquals("Session 1", viewModel.uiState.value.sessions[0].title)
assertEquals(5, viewModel.uiState.value.sessions[0].message_count)
assertEquals("active", viewModel.uiState.value.sessions[0].status)
assertEquals(
"session-123",
viewModel.uiState.value.sessions[0]
.id,
)
assertEquals(
"Session 1",
viewModel.uiState.value.sessions[0]
.title,
)
assertEquals(
5,
viewModel.uiState.value.sessions[0]
.message_count,
)
assertEquals(
"active",
viewModel.uiState.value.sessions[0]
.status,
)
}
@Test
@@ -0,0 +1,38 @@
package com.m57.hermescontrol
import org.junit.Test
import kotlin.system.measureNanoTime
class NavigationBenchmarkTest {
@Test
fun benchmarkMapToSet() {
// Simulate ALL_NAV_ITEMS which has 20 items
val items = (1..20).toList()
// Warmup
for (i in 1..10000) {
val a = items.map { it }.toSet()
val b = items.mapTo(mutableSetOf()) { it }
}
var timeMapToSet: Long = 0
var timeMapTo: Long = 0
val iterations = 100000
for (i in 1..iterations) {
timeMapToSet +=
measureNanoTime {
items.map { it }.toSet()
}
timeMapTo +=
measureNanoTime {
items.mapTo(mutableSetOf()) { it }
}
}
println("============================")
println("Baseline (.map.toSet): ${timeMapToSet / iterations} ns/op")
println("Optimized (.mapTo): ${timeMapTo / iterations} ns/op")
println("============================")
}
}