Optimise array controller addObject: by eliminating entirely pointless rearrange when added objects did not pass the filter. Also avoided double rearrange if clearsFilterPredicateOnInsertion.

CPArrayControllerPerformance.j execution time on "testAddObject_, sorted, filtered" down from ~420ms to ~60ms on my machine.
This commit is contained in:
Alexander Ljungberg committed 2011-05-28 02:02:24 -04:00
1 parent a1a06c3f75
commit 2e5081b137
2 files changed
+45 -9

No files matched your search

+20 -8
View File
@@ -719,8 +719,12 @@
if (![self canAdd])
return;
if (_clearsFilterPredicateOnInsertion)
var willClearPredicate = NO;
if (_clearsFilterPredicateOnInsertion && _filterPredicate)
{
[self willChangeValueForKey:@"filterPredicate"];
willClearPredicate = YES;
}
[self willChangeValueForKey:@"content"];
@@ -735,11 +739,15 @@
[_contentObject addObject:object];
_disableSetContent = NO;
if (_clearsFilterPredicateOnInsertion)
[self __setFilterPredicate:nil];
if (_filterPredicate === nil || [_filterPredicate evaluateWithObject:object])
if (willClearPredicate)
{
// Full rearrange needed due to changed filter.
_filterPredicate = nil;
[self _rearrangeObjects];
}
else if (_filterPredicate === nil || [_filterPredicate evaluateWithObject:object])
{
// Insert directly into the array.
var pos = [_arrangedObjects insertObject:object inArraySortedByDescriptors:_sortDescriptors];
// selectionIndexes change notification will be fired as a result of the
@@ -749,12 +757,16 @@
else
[_selectionIndexes shiftIndexesStartingAtIndex:pos by:1];
}
else
[self _rearrangeObjects];
/*
else if (_filterPredicate !== nil)
...
// Implies _filterPredicate && ![_filterPredicate evaluateWithObject:object], so the new object does
// not appear in arrangedObjects and we do not have to update at all.
*/
// This will also send notificaitons for arrangedObjects.
[self didChangeValueForKey:@"content"];
if (_clearsFilterPredicateOnInsertion)
if (willClearPredicate)
[self didChangeValueForKey:@"filterPredicate"];
}