From 688144167148a3d33719a38136f3220b53a0c89c Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sat, 10 Sep 2022 14:14:31 -0400 Subject: [PATCH] Don't use shared background context for fetching item counts A significant fraction of the time was spent waiting for the background context to be available, before the count could even be started. Since the counts don't need to use the shared background context, let them each use their own context to avoid contention. --- .../xcshareddata/xcschemes/Reader.xcscheme | 2 +- .../Screens/Home/HomeCollectionViewCell.swift | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Reader.xcodeproj/xcshareddata/xcschemes/Reader.xcscheme b/Reader.xcodeproj/xcshareddata/xcschemes/Reader.xcscheme index 262264b..f1a484a 100644 --- a/Reader.xcodeproj/xcshareddata/xcschemes/Reader.xcscheme +++ b/Reader.xcodeproj/xcshareddata/xcschemes/Reader.xcscheme @@ -77,7 +77,7 @@ + isEnabled = "NO"> diff --git a/Reader/Screens/Home/HomeCollectionViewCell.swift b/Reader/Screens/Home/HomeCollectionViewCell.swift index 2ac2b97..e19098c 100644 --- a/Reader/Screens/Home/HomeCollectionViewCell.swift +++ b/Reader/Screens/Home/HomeCollectionViewCell.swift @@ -14,7 +14,7 @@ private let signposter = OSSignposter(subsystem: "net.shadowfacts.Reader", categ class HomeCollectionViewCell: UICollectionViewListCell { - private var currentItemListType: ItemListType? + private var currentItemCountTask: Task? private var itemCount: Int? #if !targetEnvironment(macCatalyst) @@ -31,12 +31,11 @@ class HomeCollectionViewCell: UICollectionViewListCell { override func prepareForReuse() { super.prepareForReuse() + currentItemCountTask?.cancel() itemCount = nil } func updateUI(item: ItemListType, persistentContainer: PersistentContainer) { - self.currentItemListType = item - var config = UIListContentConfiguration.valueCell() config.text = item.title if let itemCount { @@ -45,10 +44,10 @@ class HomeCollectionViewCell: UICollectionViewListCell { config.secondaryTextProperties.color = .tintColor self.contentConfiguration = config - Task(priority: .userInitiated) { - let state = signposter.beginInterval("fetch count", id: signposter.makeSignpostID()) + currentItemCountTask = Task(priority: .userInitiated) { + let state = signposter.beginInterval("fetch count", id: signposter.makeSignpostID(), "\(String(item.hashValue, radix: 16), privacy: .public)") if let count = await fetchCount(item: item, in: persistentContainer), - self.currentItemListType == item { + !Task.isCancelled { self.itemCount = count config.secondaryText = count.formatted(.number) self.contentConfiguration = config @@ -62,9 +61,12 @@ class HomeCollectionViewCell: UICollectionViewListCell { return nil } return await withCheckedContinuation({ continuation in - let context = persistentContainer.backgroundContext - context.perform { + let state = signposter.beginInterval("waiting to perform", id: signposter.makeSignpostID(), "\(String(item.hashValue, radix: 16), privacy: .public)") + persistentContainer.performBackgroundTask { context in + signposter.endInterval("waiting to perform", state) + let state = signposter.beginInterval("count", id: signposter.makeSignpostID(), "\(String(item.hashValue, radix: 16), privacy: .public)") let count = try? context.count(for: request) + signposter.endInterval("count", state) continuation.resume(returning: count) } })