Skip to content

Commit

Permalink
fix(ios): optimize perf of ComponentMap and support multi-rootView
Browse files Browse the repository at this point in the history
  • Loading branch information
wwwcg authored and hippy-actions[bot] committed Jan 12, 2024
1 parent 8e51079 commit 61c52e9
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 21 deletions.
6 changes: 4 additions & 2 deletions renderer/native/ios/renderer/HippyComponentMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,12 @@ typedef NS_ENUM(NSUInteger, HippyComponentReferenceType) {
/// so we optimize this with a temporary cache.
///
/// The cache must be actively cleared after acquiring components
- (void)generateTempCacheBeforeAcquireAllStoredWeakComponents;
/// - Parameter rootTag: Root component's tag
- (void)generateTempCacheBeforeAcquireAllStoredWeakComponentsForRootTag:(NSNumber *)rootTag;

/// Clear the temp dictionary cache for weak components.
- (void)clearTempCacheAfterAcquireAllStoredWeakComponents;
/// - Parameter rootTag: Root component's tag
- (void)clearTempCacheAfterAcquireAllStoredWeakComponentsForRootTag:(NSNumber *)rootTag;

@end

Expand Down
42 changes: 27 additions & 15 deletions renderer/native/ios/renderer/HippyComponentMap.mm
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ @interface HippyComponentMap () {
NSMutableDictionary<NSNumber *, id> *_componentsMap;
std::unordered_map<int32_t, std::weak_ptr<RootNode>> _rootNodesMap;

BOOL _enableWeakComponentsTempCache;
NSDictionary *_cacheDictionaryForWeakComponents;
NSMutableDictionary<NSNumber *, NSNumber *> *_enableWeakComponentsTempCache;
NSMutableDictionary<NSNumber *, NSMutableDictionary *> *_cacheDictionaryForWeakComponentsMap;
}

@end
Expand All @@ -46,6 +46,8 @@ - (instancetype)initWithComponentsReferencedType:(HippyComponentReferenceType)ty
_rootComponentsMap = [NSMapTable strongToWeakObjectsMapTable];
_componentsMap = [NSMutableDictionary dictionary];
_rootNodesMap.reserve(8);
_enableWeakComponentsTempCache = [NSMutableDictionary dictionary];
_cacheDictionaryForWeakComponentsMap = [NSMutableDictionary dictionary];
}
return self;
}
Expand Down Expand Up @@ -108,9 +110,9 @@ - (void)addComponent:(__kindof id<HippyComponent>)component forRootTag:(NSNumber
if (component && tag) {
id map = [_componentsMap objectForKey:tag];
[map setObject:component forKey:[component hippyTag]];
if (!_isStrongHoldAllComponents && _enableWeakComponentsTempCache && _cacheDictionaryForWeakComponents) {
if (!_isStrongHoldAllComponents && _cacheDictionaryForWeakComponentsMap[tag]) {
// see `generateTempCacheBeforeAcquireAllStoredWeakComponents`
_cacheDictionaryForWeakComponents = nil;
[_cacheDictionaryForWeakComponentsMap[tag] setObject:component forKey:[component hippyTag]];
}
}
}
Expand All @@ -122,9 +124,9 @@ - (void)removeComponent:(__kindof id<HippyComponent>)component forRootTag:(NSNum
if (component && tag) {
id map = [_componentsMap objectForKey:tag];
[map removeObjectForKey:[component hippyTag]];
if (!_isStrongHoldAllComponents && _enableWeakComponentsTempCache && _cacheDictionaryForWeakComponents) {
if (!_isStrongHoldAllComponents && _cacheDictionaryForWeakComponentsMap[tag]) {
// see `generateTempCacheBeforeAcquireAllStoredWeakComponents`
_cacheDictionaryForWeakComponents = nil;
[_cacheDictionaryForWeakComponentsMap[tag] removeObjectForKey:[component hippyTag]];
}
}
}
Expand All @@ -144,11 +146,11 @@ - (void)removeComponent:(__kindof id<HippyComponent>)component forRootTag:(NSNum
// Remember:
// 1. The cache is automatically removed when a new component is inserted.
// 2. The cache must exist only temporarily, otherwise it will affect the lifecycle of the component.
if (_enableWeakComponentsTempCache) {
if (!_cacheDictionaryForWeakComponents) {
_cacheDictionaryForWeakComponents = ((NSMapTable *)map).dictionaryRepresentation;
if (_enableWeakComponentsTempCache[tag]) {
if (!_cacheDictionaryForWeakComponentsMap[tag]) {
_cacheDictionaryForWeakComponentsMap[tag] = ((NSMapTable *)map).dictionaryRepresentation.mutableCopy;
}
return _cacheDictionaryForWeakComponents;
return _cacheDictionaryForWeakComponentsMap[tag];
} else {
return ((NSMapTable *)map).dictionaryRepresentation;
}
Expand Down Expand Up @@ -189,13 +191,23 @@ - (NSString *)description {

#pragma mark -

- (void)generateTempCacheBeforeAcquireAllStoredWeakComponents {
_enableWeakComponentsTempCache = YES;
- (void)generateTempCacheBeforeAcquireAllStoredWeakComponentsForRootTag:(NSNumber *)rootTag {
NSAssert([self threadCheck], @"%@ method needs run in main thread", NSStringFromSelector(_cmd));
_enableWeakComponentsTempCache[rootTag] = @YES;
}

- (void)clearTempCacheAfterAcquireAllStoredWeakComponents {
_enableWeakComponentsTempCache = NO;
_cacheDictionaryForWeakComponents = nil;
- (void)clearTempCacheAfterAcquireAllStoredWeakComponentsForRootTag:(NSNumber *)rootTag {
NSAssert([self threadCheck], @"%@ method needs run in main thread", NSStringFromSelector(_cmd));
[_enableWeakComponentsTempCache removeObjectForKey:rootTag];
static BOOL pendingClear = NO;
if (pendingClear) {
return;
}
pendingClear = YES;
dispatch_async(dispatch_get_main_queue(), ^{
[self->_cacheDictionaryForWeakComponentsMap removeObjectForKey:rootTag];
pendingClear = NO;
});
}

@end
8 changes: 4 additions & 4 deletions renderer/native/ios/renderer/HippyUIManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ - (UIView *)createViewForShadowListItem:(HippyShadowView *)shadowView {
[shadowView synchronousRecusivelySetCreationTypeToInstant];
UIView *listItemView = [self createViewRecursiveFromRenderObjectWithNOLock:shadowView];
[self.viewRegistry generateTempCacheBeforeAcquireAllStoredWeakComponents];
[self.viewRegistry generateTempCacheBeforeAcquireAllStoredWeakComponentsForRootTag:shadowView.rootTag];
NSMutableSet<NativeRenderApplierBlock> *applierBlocks = [NSMutableSet set];
[shadowView amendLayoutBeforeMount:applierBlocks];
if (applierBlocks.count) {
Expand All @@ -534,7 +534,7 @@ - (UIView *)createViewForShadowListItem:(HippyShadowView *)shadowView {
block(viewRegistry, nil);
}
}
[self.viewRegistry clearTempCacheAfterAcquireAllStoredWeakComponents];
[self.viewRegistry clearTempCacheAfterAcquireAllStoredWeakComponentsForRootTag:shadowView.rootTag];
return listItemView;
}
Expand Down Expand Up @@ -734,7 +734,7 @@ - (void)flushUIBlocksOnRootNode:(std::weak_ptr<RootNode>)rootNode {
__strong __typeof(weakSelf)strongSelf = weakSelf;
if (strongSelf) {
TDF_PERF_LOG("flushUIBlocksOnRootNode on main thread(random id:%u)",rand);
[strongSelf.viewRegistry generateTempCacheBeforeAcquireAllStoredWeakComponents];
[strongSelf.viewRegistry generateTempCacheBeforeAcquireAllStoredWeakComponentsForRootTag:@(rootTag)];
for (HippyViewManagerUIBlock block in previousPendingUIBlocks) {
@try {
// Note: viewRegistry may be modified in the block, and it may be stored internally as NSMapTable
Expand All @@ -745,7 +745,7 @@ - (void)flushUIBlocksOnRootNode:(std::weak_ptr<RootNode>)rootNode {
HippyLogError(@"Exception thrown while executing UI block: %@", exception);
}
}
[strongSelf.viewRegistry clearTempCacheAfterAcquireAllStoredWeakComponents];
[strongSelf.viewRegistry clearTempCacheAfterAcquireAllStoredWeakComponentsForRootTag:@(rootTag)];
TDF_PERF_LOG("flushUIBlocksOnRootNode done, block count:%d(random id:%u)", previousPendingUIBlocks.count, rand);
}
});
Expand Down

0 comments on commit 61c52e9

Please sign in to comment.