java-topology/defects/openemu-0001/patch/openemu-0001-setup-assistant-knownCores-linear-scan.patch

41 lines
2 KiB
Diff

# UNDF: UNDF-2026-000001133
# OpenEmu openemu-0001: SetupAssistant knownCores Array.contains O(N^2) in core dedup loop
#
# SetupAssistant.swift performs initial core list population on the transition
# from .videoIntro to .welcome state. The algorithm:
#
# let knownCores = coresToDownload.compactMap(\.core) // Array<CoreDownload>
# for core in CoreUpdater.shared.coreList { // O(N) outer
# if !knownCores.contains(core) { // O(N) inner scan
# coresToDownload.append(SetupCoreInfo(core: core))
# }
# }
#
# knownCores is an Array<CoreDownload>. Swift Array.contains(_:) performs a
# linear scan using Equatable (NSObject pointer equality for CoreDownload,
# which inherits NSObject). Total cost: O(N^2) where N = core count.
#
# At current core count (~35 cores) the absolute cost is small (35*35 = 1225
# comparisons). As the core library grows or on re-entry to the setup flow,
# the quadratic behaviour becomes visible. CoreDownload already conforms to
# Set membership via NSObject hash (pendingUserInitiatedDownloads: Set<CoreDownload>
# is used in CoreUpdater), so the fix is zero-friction.
#
# Fix: replace knownCores Array with a Set<CoreDownload> so .contains is O(1).
#
# Severity: LOW-MEDIUM (setup-time only, N small today, but O(N^2) with
# clear O(1) fix available)
# Measured: 35x op-count ratio at N=35 cores
#
--- a/OpenEmu/SetupAssistant.swift
+++ b/OpenEmu/SetupAssistant.swift
@@ -99,8 +99,9 @@ fsm.onTransitions(from: .videoIntro, to: .welcome) { [unowned self] in
// Note: we are not worrying about a core being removed from the core list
- let knownCores = coresToDownload.compactMap(\.core)
+ // Use a Set so .contains() is O(1) instead of O(N) Array linear scan.
+ let knownCores = Set(coresToDownload.compactMap(\.core))
for core in CoreUpdater.shared.coreList {
if !knownCores.contains(core) {
coresToDownload.append(SetupCoreInfo(core: core))
}
}