41 lines
2 KiB
Diff
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))
|
|
}
|
|
}
|