Closed ghazel closed 9 years ago
I’ve had problems with UICollectionView’s
internal batch update process getting extremely slow with large updates. If you're using UICollectionView
, I would suggest profiling it.
I don't completely understand what you mean by "loading". Can you describe what components of TLIPT you're using, e.g. TLCollectionViewController
, TLIndexPathController
, etc. and how you're creating and updating your data model?
Yes, perfomBatchUpdates is hidiously slow with >100 items.
By loading I mean; setting items
, which builds all the lookup tables. Easy to see in the Shuffle/Filter demo by making an array of 5k items (make sure they are unique).
I was able to get the Shuffle demo with 5000 items in Simulator down to 2.5s from 15s. The remaining 2.5s was made up of:
[UICollectionView _endItemAnimations]
mainly manipulating index paths. There is nothing I can do about this.AutoReleasePoolPage::pop(void*)
. A lot of this is likely due to temporary objects created in TLIndexPathUpdates
, but I don't know how much this can be improved and it could be a significant undertaking that I don't have time for.The issue is summarized as follows. Ultimately, the problem was that the data model items were arrays:
NSArray *items = @[
@[@"A", [UIColor colorWithHexRGB:0x443695]],
@[@"B", [UIColor colorWithHexRGB:0x00B1D7]],
@[@"C", [UIColor colorWithHexRGB:0xF42994]],
@[@"D", [UIColor colorWithHexRGB:0x0A0916]],
@[@"E", [UIColor colorWithHexRGB:0xF4E353]],
@[@"F", [UIColor colorWithHexRGB:0x537B28]],
];
TLIPT was calling isEqual
on these arrays a lot and this was really slow. The fix involves two changes. The first change was a performance optimization I made in TLIPT to eliminate a bunch of isEqual
calls. You'll need to update to version 0.3.8. The second change, which is something you'll probably need to do in our code, was to provide an explicit identifier for each data model item. isEqual
gets called on the identifier instead of the item and, with an appropriate choice of identifier, this is much, much faster.
Item identifiers are discussed in the TLIndexPathDataModel
API documentation in the "Item Identification" section. The short story is that, in some cases such as the Shuffle example, the item itself is used as the identifier. And if the item's isEqual
method is expensive, the data model will not scale. The way to fix this is to provide an explicit unique identifier with a fast isEqual
method, such as an NSString
. The various TLIndexPathDataModel
initializers provide a few options for specifying identifiers. In the Shuffle example, I used the block-based initializer and the first element of the array, i.e. the unique string, as the identifier:
self.indexPathController.dataModel = [[TLIndexPathDataModel alloc] initWithItems:items sectionNameBlock:nil identifierBlock:^id(id item) {
return item[0];
}];
Thats about it. Please let me know if this helps your project.
No reply. Closing.
With a data set of 10k items, the TLIndexPathDataModel takes 45 seconds to load. With 5k items, it takes 11 seconds. With 1k items it loads in under a second.
What is it doing which is so non-linear?