Visualizer Optimization Plan #7
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
AI Agent Directives: iOS Visualizer Refactor & Optimization
Role & Context
You are an expert Apple platforms performance engineer specializing in high-performance SwiftUI, memory management, and vDSP. We are optimizing an iOS audio visualizer (
MitsuhaVisualizerView) that reads pre-computed offline FFT data.The core issue is severe memory allocation overhead. The app is dropping frames because we are heavily allocating
[Float]arrays both during ingestion and inside the 60fps render loop.🛑 Strict Invariants
TimelineView/Canvasrender loop andupdateDisplayLevelsMUST allocate zero new memory. Mutate existing buffers in-place.PlaygroundSupport.levelHistoryBuf). It perfectly matches the desired visual style.Execution Plan
Execute these tasks sequentially.
Phase 1: Flat Memory-Mapped Storage (
VisualizerStorageManager.swift)The current
loadCachemethod reads the file and allocates an expensive[[Float]]array of arrays.loadCacheto useData(contentsOf: url, options: .alwaysMapped).[[Float]], return a highly efficient struct or tuple containing:ContiguousArray<Float>(or directly expose the mappedUnsafeBufferPointerif safe to do so).frameCount(UInt32)pointsPerFrame(UInt32)saveCacheto accept and write this flat format if necessary, though it currently writes sequentially perfectly fine.Phase 2: Zero-Allocation Display Updates (
MitsuhaVisualizerView.swift)The
updateDisplayLevelsmethod currently creates a newvar targetLevels = [Float]()array 60 times a second.VisualizerLevelBoxto pre-allocatetargetLevelsmatchingsettings.numberOfPointson initialization.updateDisplayLevelsso that it mutates this pre-allocatedtargetLevelsbuffer in-place using standardforloops.newRawLevelsarray size differs fromcount, perform the linear interpolation directly into the pre-allocated buffer without instantiating any intermediate collections.Phase 3: The View Invalidation Audit
MitsuhaVisualizerView. Ensure that the@ObservedObject var settingsand@StateObject private var boxare not causing the parent view to invalidate on every timeline tick. TheCanvasshould be the only thing redrawing. Ensure variables captured by theCanvasclosure are tight and efficient.