Open maxbrogno opened 4 years ago
Good idea. It'd be a great chance for learning too. I hope somebody jumps in and works on this.
I'd love to have this one too.
Hello there!
I've started working on some iOS 14 widgets for CoronaTracker, but I've hit a problem: the peak memory usage for a widget cannot exceed 30 Mb.
Currently, getting all the data from DataManager.shared.download
takes the memory usage to ~39 Mb
.
I've stripped out getting time series data from JHU (JHURepoDataService.shared.fetchTimeSerieses
) and managed to reduce the memory footprint to ~ 31 Mb
.
@mhdhejazi , is there a simple way to fetch some basic data (ex. just the dailyChange
) for a single Region
?
P.S: This is also the reason why the existing Today Extension is not working any more. P.P.S: Here's a sneak peak on how they currently look (the simulator does not have this limitation) 😉
Looks great!
I think I managed to solve the issue...
By looking at memory allocations, I've found that JHURepoDataService.parseTimeSerieses(data:, completion:)
had the heaviest memory footprint. This was mainly because it took all 270
header values that represented time series dates and stored them as strings. Then, for every value in every time series (probably hundreds of thousands) called
let dateStrings = headers.dropFirst(4)
if let date = dateFormatter.date(from: dateString) {
for confirmedTimeSeries in confirmed {
for column in confirmedTimeSeries.values.indices {
let dateString = dateStrings[dateStrings.startIndex + column]
if let date = dateFormatter.date(from: dateString) {
...
}
}
}
}
All the calls to .date(from: dateString
) increase a lot the amount of memory used (and computation time).
The solution was to parse only the header values as dates and use them later in the process (this also comes with a great performance improvement):
let dateStrings = headers.dropFirst(4)
let dateValues = dateStrings.compactMap({ dateFormatter.date(from: $0) })
if let date = dateFormatter.date(from: dateString) {
for confirmedTimeSeries in confirmed {
for column in confirmedTimeSeries.values.indices {
let dateString = dateStrings[dateStrings.startIndex + column]
let date = dateValues[column]
...
}
}
}
Managed to reduce the memory used by a widget to ~15Mb
from ~39Mb
👍
I still have to do a bit of more UI polishing and create a pull request (most likely tomorrow).
Wow, great work there and a nice catch. When I created the app the dataset was relatively small (both horizontally and vertically), so I didn't see the memory and performance issue. Thank you for fixing that.
Another idea to improve performance and memory usage could be by only parsing the data relevant to the current region. It could be challenging to do that without a big refactoring, but you can take a look at it.
@mhdhejazi - just made a PR that only addresses the memory reduction stuff (https://github.com/mhdhejazi/CoronaTracker/pull/133)
it seems its solved in https://github.com/mhdhejazi/CoronaTracker/pull/134 ?
Any chance someone is working on a new iOS 14 home screen widget for the app? Would love to be able to have my local numbers easily visible.