My app allows the user to record audio. I'm using a
ContiguousArray to store the raw audio samples. The size of the array is often very large (>1,000,000 samples). As audio is recorded, the samples are appended to the array. The final size of the array is always known before recording starts. So to avoid reallocations, I call
reserveCapacity() before recording.
Despite this, I've found that ContiguousArray seems to change its
capacity to slightly more than its
count almost every time I call
append(contentsOf:). Because of this, the copying and reallocation starts to get pretty expensive towards the end of the user's recording. Time Profiler shows that
ContiguousArray._copyToNewBuffer(oldCount:) is taking up a lot of CPU cycles:
And CPU usage grows exponentially throughout the recording, indicating that the appends are not O(1) like the documentation claims. Instead they seem to be O(n), where n is the array's
count before appending.
reserveCapacity() again after every append is not a solution, since this forces the array to reallocate again. This results in worse performance.
Am I misunderstanding the point of
reserveCapacity()? What's the point of calling it if
ContiguousArray reallocates itself anyways every time I append to it? How do I get it to hold its capacity through multiple appends over >60 seconds of recording?