改进了为大型数据集下载图像的内存性能

Memory performance improvement for downloading images for a large dataset

提问人:Yousif Ismat 提问时间:9/27/2023 更新时间:9/27/2023 访问量:24

问:

我目前正在制作一个程序,该程序从 url 中获取电影/连续剧详细信息并将它们解码为 ContentModel,然后尝试下载模型中每个 posterURL 的图像,然后返回它:

struct ContentModel: Decodable {
    let url: URL
    let title: String
    let type: String
    let posterUrl: URL
    let description: String
    let aggregateRating: AggregateRating?
    let contentRating: String?
    let genre: [String]
    let trailer: Trailer?
    let actor: [Individual]
    let director: [Individual]
}

func parseContentJSON(_ contentID: String) async throws -> ContentModel {
        
        // hidden code: url setting, calling session, getting response and data
        
        do {
            var content = try jsonDecoder.decode(Short.self, from: data).short
            content.poster = await downloadImage(from: content.posterUrl) //performs affecting line
            return content
        } catch {
            throw ParseError.invalidData
        }
    }

当我只调用该函数并且不尝试使用 downloadImage(from:) 设置 content.poster 时,内存性能固定在 25MB 左右,但是当添加该行时,如上述代码所示,并且此函数被调用大约 50 次,内存使用量跃升至 800MB(我预计它会随着更多函数调用而增加更多)这是不可持续的, 有没有办法降低内存性能?

我在下面的上下文中调用该函数

let contentsID: [String] = [...] // about 50 IDs in it

func loadContentConcurrent(start startIndex: Int, end endIndex: Int) async {
        var all: [ContentModel] = []
        
        try? await withThrowingTaskGroup(of: ContentModel?.self) { group in
            for contentID in contentsID[startIndex..<endIndex] {
                group.addTask {
                    // TODO: creates memory leak; work on this
                    return try? await self.parseContentJSON(contentID)
                }
            }
            
            for try await contentFound in group {
                if let safeContent = contentFound {
                    all.append(safeContent)
                }
            }
            return
        }
        
        DispatchQueue.main.async { [weak self, all] in
            self?.contents += all
            self?.contentLoadedCount += all.count
        }
        
    }

为了消除歧义,这些道具和方法位于 ViewModel 中,我在初始值设定项中调用该函数一次,然后从与 ViewModel 关联的 View 中定期调用它。我正在使用分页技术(即每隔一段时间在 5 个 id 的垃圾中调用此函数,而不是 ContentID 列表中的所有 50 个 id。

Swift Xcode 异步 管理内存 泄漏

评论

0赞 Joakim Danielson 9/27/2023
图像有多大,你能降低它们的占用率和/或质量吗?也许将它们保存在本地,只在需要时将它们加载到内存中?
0赞 Yousif Ismat 9/27/2023
图像大小大多是 1900 × 2814,我不确定如何在获取时降低它们的质量。此外,我不想在本地保存图像,因为 contentID 稍后将使用其他内容动态更新,因此会更新新的 contentID,这将破坏这一点。
0赞 Joakim Danielson 9/27/2023
在应用程序运行时,您仍然可以将它们临时存储到磁盘上。我的意思是在保存到磁盘时减小大小。
0赞 Yousif Ismat 9/27/2023
这怎么可能?
0赞 Joakim Danielson 9/27/2023
有什么可能?

答: 暂无答案