Reduce block invocations, other small performance bumps

This commit is contained in:
Adlai Holler
2016-07-12 13:50:20 -07:00
parent e40597ec47
commit 2e19d11350
8 changed files with 103 additions and 77 deletions

View File

@@ -303,9 +303,9 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
- (void)removeControls - (void)removeControls
{ {
NSArray *controls = [_cachedControls allValues]; NSArray *controls = [_cachedControls allValues];
[controls enumerateObjectsUsingBlock:^(ASDisplayNode *_Nonnull node, NSUInteger idx, BOOL * _Nonnull stop) { for (ASDisplayNode *node in controls) {
[node removeFromSupernode]; [node removeFromSupernode];
}]; }
[self cleanCachedControls]; [self cleanCachedControls];
} }

View File

@@ -117,16 +117,18 @@
- (void)willMoveSection:(NSInteger)section toSection:(NSInteger)newSection - (void)willMoveSection:(NSInteger)section toSection:(NSInteger)newSection
{ {
for (NSString *kind in [self supplementaryKinds]) { for (NSString *kind in [self supplementaryKinds]) {
NSArray *indexPaths = ASIndexPathsForMultidimensionalArrayAtIndexSet([self editingNodesOfKind:kind], [NSIndexSet indexSetWithIndex:section]); NSMutableArray *editingNodes = [self editingNodesOfKind:kind];
NSArray *nodes = ASFindElementsInMultidimensionalArrayAtIndexPaths([self editingNodesOfKind:kind], indexPaths); NSArray *indexPaths = ASIndexPathsForMultidimensionalArrayAtIndexSet(editingNodes, [NSIndexSet indexSetWithIndex:section]);
NSArray *nodes = ASFindElementsInMultidimensionalArrayAtIndexPaths(editingNodes, indexPaths);
[self deleteNodesOfKind:kind atIndexPaths:indexPaths completion:nil]; [self deleteNodesOfKind:kind atIndexPaths:indexPaths completion:nil];
// update the section of indexpaths // update the section of indexpaths
NSIndexPath *sectionIndexPath = [[NSIndexPath alloc] initWithIndex:newSection];
NSMutableArray *updatedIndexPaths = [[NSMutableArray alloc] initWithCapacity:indexPaths.count]; NSMutableArray *updatedIndexPaths = [[NSMutableArray alloc] initWithCapacity:indexPaths.count];
[indexPaths enumerateObjectsUsingBlock:^(NSIndexPath *indexPath, NSUInteger idx, BOOL *stop) { for (NSIndexPath *indexPath in indexPaths) {
[updatedIndexPaths addObject:[sectionIndexPath indexPathByAddingIndex:[indexPath indexAtPosition:indexPath.length - 1]]]; NSUInteger newItem = [indexPath indexAtPosition:indexPath.length - 1];
}]; NSIndexPath *mappedIndexPath = [NSIndexPath indexPathForItem:newItem inSection:newSection];
[updatedIndexPaths addObject:mappedIndexPath];
}
[self insertNodes:nodes ofKind:kind atIndexPaths:indexPaths completion:nil]; [self insertNodes:nodes ofKind:kind atIndexPaths:indexPaths completion:nil];
} }
} }
@@ -204,12 +206,13 @@
id<ASEnvironment> environment = [self.environmentDelegate dataControllerEnvironment]; id<ASEnvironment> environment = [self.environmentDelegate dataControllerEnvironment];
ASEnvironmentTraitCollection environmentTraitCollection = environment.environmentTraitCollection; ASEnvironmentTraitCollection environmentTraitCollection = environment.environmentTraitCollection;
[sections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { [sections enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
NSUInteger rowNum = [self.collectionDataSource dataController:self supplementaryNodesOfKind:kind inSection:idx]; for (NSUInteger sec = range.location; sec < NSMaxRange(range); sec++) {
NSIndexPath *sectionIndex = [[NSIndexPath alloc] initWithIndex:idx]; NSUInteger itemCount = [self.collectionDataSource dataController:self supplementaryNodesOfKind:kind inSection:sec];
for (NSUInteger i = 0; i < rowNum; i++) { for (NSUInteger i = 0; i < itemCount; i++) {
NSIndexPath *indexPath = [sectionIndex indexPathByAddingIndex:i]; NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:sec];
[self _populateSupplementaryNodeOfKind:kind atIndexPath:indexPath mutableContexts:contexts environmentTraitCollection:environmentTraitCollection]; [self _populateSupplementaryNodeOfKind:kind atIndexPath:indexPath mutableContexts:contexts environmentTraitCollection:environmentTraitCollection];
}
} }
}]; }];
} }
@@ -224,12 +227,13 @@
[sections addIndex:indexPath.section]; [sections addIndex:indexPath.section];
} }
[sections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { [sections enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
NSUInteger rowNum = [self.collectionDataSource dataController:self supplementaryNodesOfKind:kind inSection:idx]; for (NSUInteger sec = range.location; sec < NSMaxRange(range); sec++) {
NSIndexPath *sectionIndex = [[NSIndexPath alloc] initWithIndex:idx]; NSUInteger itemCount = [self.collectionDataSource dataController:self supplementaryNodesOfKind:kind inSection:sec];
for (NSUInteger i = 0; i < rowNum; i++) { for (NSUInteger i = 0; i < itemCount; i++) {
NSIndexPath *indexPath = [sectionIndex indexPathByAddingIndex:i]; NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:sec];
[self _populateSupplementaryNodeOfKind:kind atIndexPath:indexPath mutableContexts:contexts environmentTraitCollection:environmentTraitCollection]; [self _populateSupplementaryNodeOfKind:kind atIndexPath:indexPath mutableContexts:contexts environmentTraitCollection:environmentTraitCollection];
}
} }
}]; }];
} }

View File

@@ -302,8 +302,9 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
_editingNodes[kind] = editingNodes; _editingNodes[kind] = editingNodes;
[_mainSerialQueue performBlockOnMainThread:^{ [_mainSerialQueue performBlockOnMainThread:^{
NSArray *nodes = ASFindElementsInMultidimensionalArrayAtIndexPaths(_completedNodes[kind], indexPaths); NSMutableArray *allNodes = _completedNodes[kind];
ASDeleteElementsInMultidimensionalArrayAtIndexPaths(_completedNodes[kind], indexPaths); NSArray *nodes = ASFindElementsInMultidimensionalArrayAtIndexPaths(allNodes, indexPaths);
ASDeleteElementsInMultidimensionalArrayAtIndexPaths(allNodes, indexPaths);
if (completionBlock) { if (completionBlock) {
completionBlock(nodes, indexPaths); completionBlock(nodes, indexPaths);
} }
@@ -512,17 +513,19 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
ASEnvironmentTraitCollection environmentTraitCollection = environment.environmentTraitCollection; ASEnvironmentTraitCollection environmentTraitCollection = environment.environmentTraitCollection;
NSMutableArray<ASIndexedNodeContext *> *contexts = [NSMutableArray array]; NSMutableArray<ASIndexedNodeContext *> *contexts = [NSMutableArray array];
[indexSet enumerateIndexesUsingBlock:^(NSUInteger sectionIndex, BOOL *stop) { [indexSet enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
NSUInteger rowNum = [_dataSource dataController:self rowsInSection:sectionIndex]; for (NSUInteger sectionIndex = range.location; sectionIndex < NSMaxRange(range); sectionIndex++) {
for (NSUInteger i = 0; i < rowNum; i++) { NSUInteger itemCount = [_dataSource dataController:self rowsInSection:sectionIndex];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:sectionIndex]; for (NSUInteger i = 0; i < itemCount; i++) {
ASCellNodeBlock nodeBlock = [_dataSource dataController:self nodeBlockAtIndexPath:indexPath]; NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:sectionIndex];
ASCellNodeBlock nodeBlock = [_dataSource dataController:self nodeBlockAtIndexPath:indexPath];
ASSizeRange constrainedSize = [self constrainedSizeForNodeOfKind:ASDataControllerRowNodeKind atIndexPath:indexPath];
[contexts addObject:[[ASIndexedNodeContext alloc] initWithNodeBlock:nodeBlock ASSizeRange constrainedSize = [self constrainedSizeForNodeOfKind:ASDataControllerRowNodeKind atIndexPath:indexPath];
indexPath:indexPath [contexts addObject:[[ASIndexedNodeContext alloc] initWithNodeBlock:nodeBlock
constrainedSize:constrainedSize indexPath:indexPath
environmentTraitCollection:environmentTraitCollection]]; constrainedSize:constrainedSize
environmentTraitCollection:environmentTraitCollection]];
}
} }
}]; }];
return contexts; return contexts;
@@ -564,10 +567,12 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
// Running these commands may result in blocking on an _editingTransactionQueue operation that started even before -beginUpdates. // Running these commands may result in blocking on an _editingTransactionQueue operation that started even before -beginUpdates.
// Each subsequent command in the queue will also wait on the full asynchronous completion of the prior command's edit transaction. // Each subsequent command in the queue will also wait on the full asynchronous completion of the prior command's edit transaction.
LOG(@"endUpdatesWithCompletion - %zd blocks to run", _pendingEditCommandBlocks.count); LOG(@"endUpdatesWithCompletion - %zd blocks to run", _pendingEditCommandBlocks.count);
[_pendingEditCommandBlocks enumerateObjectsUsingBlock:^(dispatch_block_t block, NSUInteger idx, BOOL *stop) { NSUInteger i = 0;
LOG(@"endUpdatesWithCompletion - running block #%zd", idx); for (dispatch_block_t block in _pendingEditCommandBlocks) {
LOG(@"endUpdatesWithCompletion - running block #%zd", i);
block(); block();
}]; i += 1;
}
[_pendingEditCommandBlocks removeAllObjects]; [_pendingEditCommandBlocks removeAllObjects];
[_editingTransactionQueue addOperationWithBlock:^{ [_editingTransactionQueue addOperationWithBlock:^{
@@ -861,8 +866,8 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
[_editingTransactionQueue addOperationWithBlock:^{ [_editingTransactionQueue addOperationWithBlock:^{
LOG(@"Edit Transaction - moveRow: %@ > %@", indexPath, newIndexPath); LOG(@"Edit Transaction - moveRow: %@ > %@", indexPath, newIndexPath);
NSArray *nodes = ASFindElementsInMultidimensionalArrayAtIndexPaths(_editingNodes[ASDataControllerRowNodeKind], @[indexPath]);
NSArray *indexPaths = @[indexPath]; NSArray *indexPaths = @[indexPath];
NSArray *nodes = ASFindElementsInMultidimensionalArrayAtIndexPaths(_editingNodes[ASDataControllerRowNodeKind], indexPaths);
[self _deleteNodesAtIndexPaths:indexPaths withAnimationOptions:animationOptions]; [self _deleteNodesAtIndexPaths:indexPaths withAnimationOptions:animationOptions];
// Don't re-calculate size for moving // Don't re-calculate size for moving
@@ -876,12 +881,13 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
- (NSArray *)indexPathsForEditingNodesOfKind:(NSString *)kind - (NSArray *)indexPathsForEditingNodesOfKind:(NSString *)kind
{ {
return _editingNodes[kind] != nil ? ASIndexPathsForTwoDimensionalArray(_editingNodes[kind]) : nil; NSArray *nodes = _editingNodes[kind];
return nodes != nil ? ASIndexPathsForTwoDimensionalArray(nodes) : nil;
} }
- (NSMutableArray *)editingNodesOfKind:(NSString *)kind - (NSMutableArray *)editingNodesOfKind:(NSString *)kind
{ {
return _editingNodes[kind] != nil ? _editingNodes[kind] : [NSMutableArray array]; return _editingNodes[kind] ? : [NSMutableArray array];
} }
- (NSMutableArray *)completedNodesOfKind:(NSString *)kind - (NSMutableArray *)completedNodesOfKind:(NSString *)kind
@@ -958,7 +964,7 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
- (void)dealloc - (void)dealloc
{ {
ASDisplayNodeAssertMainThread(); ASDisplayNodeAssertMainThread();
[_completedNodes enumerateKeysAndObjectsUsingBlock:^(NSString *kind, NSMutableArray *sections, BOOL *stop) { for (NSMutableArray *sections in [_completedNodes objectEnumerator]) {
for (NSArray *section in sections) { for (NSArray *section in sections) {
for (ASCellNode *node in section) { for (ASCellNode *node in section) {
if (node.isNodeLoaded) { if (node.isNodeLoaded) {
@@ -970,7 +976,7 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
} }
} }
} }
}]; }
} }
@end @end

View File

@@ -113,11 +113,11 @@
range.start = currentIndexPath; range.start = currentIndexPath;
range.end = currentIndexPath; range.end = currentIndexPath;
[indexPaths enumerateObjectsUsingBlock:^(NSIndexPath *indexPath, NSUInteger idx, BOOL *stop) { for (NSIndexPath *indexPath in indexPaths) {
currentIndexPath = [indexPath ASIndexPathValue]; currentIndexPath = [indexPath ASIndexPathValue];
range.start = ASIndexPathMinimum(range.start, currentIndexPath); range.start = ASIndexPathMinimum(range.start, currentIndexPath);
range.end = ASIndexPathMaximum(range.end, currentIndexPath); range.end = ASIndexPathMaximum(range.end, currentIndexPath);
}]; }
return range; return range;
} }

View File

@@ -15,10 +15,12 @@
- (NSIndexSet *)as_indexesByMapping:(NSUInteger (^)(NSUInteger))block - (NSIndexSet *)as_indexesByMapping:(NSUInteger (^)(NSUInteger))block
{ {
NSMutableIndexSet *result = [NSMutableIndexSet indexSet]; NSMutableIndexSet *result = [NSMutableIndexSet indexSet];
[self enumerateIndexesUsingBlock:^(NSUInteger idx, __unused BOOL * _Nonnull stop) { [self enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
NSUInteger newIndex = block(idx); for (NSUInteger i = range.location; i < NSMaxRange(range); i++) {
if (newIndex != NSNotFound) { NSUInteger newIndex = block(i);
[result addIndex:newIndex]; if (newIndex != NSNotFound) {
[result addIndex:newIndex];
}
} }
}]; }];
return result; return result;
@@ -49,11 +51,13 @@
- (NSUInteger)as_indexChangeByInsertingItemsBelowIndex:(NSUInteger)index - (NSUInteger)as_indexChangeByInsertingItemsBelowIndex:(NSUInteger)index
{ {
__block NSUInteger newIndex = index; __block NSUInteger newIndex = index;
[self enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) { [self enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
if (idx <= newIndex) { for (NSUInteger i = range.location; i < NSMaxRange(range); i++) {
newIndex += 1; if (i <= newIndex) {
} else { newIndex += 1;
*stop = YES; } else {
*stop = YES;
}
} }
}]; }];
return newIndex - index; return newIndex - index;
@@ -64,9 +68,9 @@
NSMutableString *result = [NSMutableString stringWithString:@"{ "]; NSMutableString *result = [NSMutableString stringWithString:@"{ "];
[self enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) { [self enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
if (range.length == 1) { if (range.length == 1) {
[result appendFormat:@"%lu ", (unsigned long)range.location]; [result appendFormat:@"%zu ", range.location];
} else { } else {
[result appendFormat:@"%lu-%lu ", (unsigned long)range.location, (unsigned long)NSMaxRange(range)]; [result appendFormat:@"%zu-%zu ", range.location, NSMaxRange(range) - 1];
} }
}]; }];
[result appendString:@"}"]; [result appendString:@"}"];

View File

@@ -148,9 +148,11 @@ typedef std::map<unsigned long, id<ASLayoutable>, std::less<unsigned long>> ASCh
ASDisplayNodeAssert(self.isMutable, @"Cannot set properties when layout spec is not mutable"); ASDisplayNodeAssert(self.isMutable, @"Cannot set properties when layout spec is not mutable");
_children.clear(); _children.clear();
[children enumerateObjectsUsingBlock:^(id<ASLayoutable> _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { NSUInteger i = 0;
_children[idx] = [self layoutableToAddFromLayoutable:obj]; for (id<ASLayoutable> child in children) {
}]; _children[i] = [self layoutableToAddFromLayoutable:child];
i += 1;
}
} }
- (id<ASLayoutable>)childForIndex:(NSUInteger)index - (id<ASLayoutable>)childForIndex:(NSUInteger)index

View File

@@ -171,8 +171,10 @@ NSArray *ASFindElementsInMultidimensionalArrayAtIndexPaths(NSMutableArray *mutab
NSArray *ASIndexPathsForMultidimensionalArrayAtIndexSet(NSArray *multidimensionalArray, NSIndexSet *indexSet) NSArray *ASIndexPathsForMultidimensionalArrayAtIndexSet(NSArray *multidimensionalArray, NSIndexSet *indexSet)
{ {
NSMutableArray *res = [NSMutableArray array]; NSMutableArray *res = [NSMutableArray array];
[indexSet enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { [indexSet enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
ASRecursivelyFindIndexPathsForMultidimensionalArray(multidimensionalArray[idx], [NSIndexPath indexPathWithIndex:idx], res); for (NSUInteger i = range.location; i < NSMaxRange(range); i++) {
ASRecursivelyFindIndexPathsForMultidimensionalArray(multidimensionalArray[i], [NSIndexPath indexPathWithIndex:i], res);
}
}]; }];
return res; return res;

View File

@@ -314,8 +314,10 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
NSMutableIndexSet *allIndexes = [NSMutableIndexSet new]; NSMutableIndexSet *allIndexes = [NSMutableIndexSet new];
for (_ASHierarchySectionChange *change in changes) { for (_ASHierarchySectionChange *change in changes) {
[change.indexSet enumerateIndexesUsingBlock:^(NSUInteger idx, __unused BOOL *stop) { [change.indexSet enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
animationOptions[@(idx)] = @(change.animationOptions); for (NSUInteger i = range.location; i < NSMaxRange(range); i++) {
animationOptions[@(i)] = @(change.animationOptions);
}
}]; }];
[allIndexes addIndexes:change.indexSet]; [allIndexes addIndexes:change.indexSet];
} }
@@ -326,24 +328,30 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
__block ASDataControllerAnimationOptions currentOptions = 0; __block ASDataControllerAnimationOptions currentOptions = 0;
NSMutableIndexSet *currentIndexes = [NSMutableIndexSet indexSet]; NSMutableIndexSet *currentIndexes = [NSMutableIndexSet indexSet];
NSEnumerationOptions options = type == _ASHierarchyChangeTypeDelete ? NSEnumerationReverse : kNilOptions; BOOL reverse = type == _ASHierarchyChangeTypeDelete;
NSEnumerationOptions options = reverse ? NSEnumerationReverse : kNilOptions;
[allIndexes enumerateIndexesWithOptions:options usingBlock:^(NSUInteger idx, __unused BOOL * stop) { [allIndexes enumerateRangesWithOptions:options usingBlock:^(NSRange range, BOOL * _Nonnull stop) {
ASDataControllerAnimationOptions options = [animationOptions[@(idx)] integerValue]; NSInteger increment = reverse ? -1 : 1;
NSUInteger start = reverse ? NSMaxRange(range) - 1 : range.location;
// End the previous group if needed. NSInteger limit = reverse ? range.location - 1 : NSMaxRange(range);
if (options != currentOptions && currentIndexes.count > 0) { for (NSInteger i = start; i != limit; i += increment) {
_ASHierarchySectionChange *change = [[_ASHierarchySectionChange alloc] initWithChangeType:type indexSet:[currentIndexes copy] animationOptions:currentOptions]; ASDataControllerAnimationOptions options = [animationOptions[@(i)] integerValue];
[result addObject:change];
[currentIndexes removeAllIndexes]; // End the previous group if needed.
if (options != currentOptions && currentIndexes.count > 0) {
_ASHierarchySectionChange *change = [[_ASHierarchySectionChange alloc] initWithChangeType:type indexSet:[currentIndexes copy] animationOptions:currentOptions];
[result addObject:change];
[currentIndexes removeAllIndexes];
}
// Start a new group if needed.
if (currentIndexes.count == 0) {
currentOptions = options;
}
[currentIndexes addIndex:i];
} }
// Start a new group if needed.
if (currentIndexes.count == 0) {
currentOptions = options;
}
[currentIndexes addIndex:idx];
}]; }];
// Finish up the last group. // Finish up the last group.