Make yoga & layout specs faster by eliminating some copies (#1128)

This commit is contained in:
Adlai Holler 2018-09-18 07:26:29 -07:00 committed by Huy Nguyen
parent 47e2b9c0de
commit d2984ced8d
7 changed files with 39 additions and 22 deletions

View File

@ -46,6 +46,7 @@
- Unlock before cleanup and calling out to subclass hooks for animated images. [Michael Schneider](https://github.com/maicki) [#1087](https://github.com/TextureGroup/Texture/pull/1087)
- [ASDisplayNode] Fix interface state update for layer backed nodes when layer thrashes (interface coaleascing case).[Max Wang](https://github.com/wsdwsd0829). [#1111](https://github.com/TextureGroup/Texture/pull/1111)
- [ASPINRemoteImageManager] Add a new API for setting a preconfigured PINRemoteImageManager. [Ernest Ma](https://github.com/ernestmama) [#1124](https://github.com/TextureGroup/Texture/pull/1124)
- Small optimization to the layout spec & yoga layout systems by eliminating array copies. [Adlai Holler](https://github.com/Adlai-Holler)
## 2.7
- Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877)

View File

@ -13,6 +13,7 @@
#import <AsyncDisplayKit/_ASDisplayViewAccessiblity.h>
#import <AsyncDisplayKit/ASYogaUtilities.h>
#import <AsyncDisplayKit/ASCollections.h>
#import <AsyncDisplayKit/ASDisplayNode+Beta.h>
#import <AsyncDisplayKit/ASDisplayNode+FrameworkPrivate.h>
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
@ -155,10 +156,12 @@
ASDisplayNodeAssert(childCount == self.yogaChildren.count,
@"Yoga tree should always be in sync with .yogaNodes array! %@", self.yogaChildren);
NSMutableArray *sublayouts = [NSMutableArray arrayWithCapacity:childCount];
ASLayout *rawSublayouts[childCount];
int i = 0;
for (ASDisplayNode *subnode in self.yogaChildren) {
[sublayouts addObject:[subnode layoutForYogaNode]];
rawSublayouts[i++] = [subnode layoutForYogaNode];
}
let sublayouts = [NSArray<ASLayout *> arrayByTransferring:rawSublayouts count:childCount];
// The layout for self should have position CGPointNull, but include the calculated size.
CGSize size = CGSizeMake(YGNodeLayoutGetWidth(yogaNode), YGNodeLayoutGetHeight(yogaNode));

View File

@ -9,6 +9,7 @@
#import <AsyncDisplayKit/ASAbsoluteLayoutSpec.h>
#import <AsyncDisplayKit/ASCollections.h>
#import <AsyncDisplayKit/ASLayout.h>
#import <AsyncDisplayKit/ASLayoutSpec+Subclasses.h>
#import <AsyncDisplayKit/ASLayoutSpecUtilities.h>
@ -64,7 +65,8 @@
};
NSArray *children = self.children;
NSMutableArray *sublayouts = [NSMutableArray arrayWithCapacity:children.count];
ASLayout *rawSublayouts[children.count];
int i = 0;
for (id<ASLayoutElement> child in children) {
CGPoint layoutPosition = child.style.layoutPosition;
@ -77,13 +79,14 @@
ASLayout *sublayout = [child layoutThatFits:childConstraint parentSize:size];
sublayout.position = layoutPosition;
[sublayouts addObject:sublayout];
rawSublayouts[i++] = sublayout;
}
let sublayouts = [NSArray<ASLayout *> arrayByTransferring:rawSublayouts count:i];
if (_sizing == ASAbsoluteLayoutSpecSizingSizeToFit || isnan(size.width)) {
size.width = constrainedSize.min.width;
for (ASLayout *sublayout in sublayouts) {
size.width = MAX(size.width, sublayout.position.x + sublayout.size.width);
size.width = MAX(size.width, sublayout.position.x + sublayout.size.width);
}
}

View File

@ -12,6 +12,7 @@
#import <AsyncDisplayKit/ASLayoutSpec+Subclasses.h>
#import <AsyncDisplayKit/ASAssert.h>
#import <AsyncDisplayKit/ASCollections.h>
static NSUInteger const kForegroundChildIndex = 0;
static NSUInteger const kBackgroundChildIndex = 1;
@ -48,17 +49,19 @@ static NSUInteger const kBackgroundChildIndex = 1;
{
ASLayout *contentsLayout = [self.child layoutThatFits:constrainedSize parentSize:parentSize];
NSMutableArray *sublayouts = [NSMutableArray arrayWithCapacity:2];
ASLayout *rawSublayouts[2];
int i = 0;
if (self.background) {
// Size background to exactly the same size.
ASLayout *backgroundLayout = [self.background layoutThatFits:ASSizeRangeMake(contentsLayout.size)
parentSize:parentSize];
backgroundLayout.position = CGPointZero;
[sublayouts addObject:backgroundLayout];
rawSublayouts[i++] = backgroundLayout;
}
contentsLayout.position = CGPointZero;
[sublayouts addObject:contentsLayout];
rawSublayouts[i++] = contentsLayout;
let sublayouts = [NSArray<ASLayout *> arrayByTransferring:rawSublayouts count:i];
return [ASLayout layoutWithLayoutElement:self size:contentsLayout.size sublayouts:sublayouts];
}

View File

@ -113,14 +113,12 @@ ASLayoutElementLayoutCalculationDefaults
{
ASDisplayNodeAssert(self.isMutable, @"Cannot set properties when layout spec is not mutable");
[_childrenArray removeAllObjects];
NSUInteger i = 0;
#if ASDISPLAYNODE_ASSERTIONS_ENABLED
for (id<ASLayoutElement> child in children) {
ASDisplayNodeAssert([child conformsToProtocol:NSProtocolFromString(@"ASLayoutElement")], @"Child %@ of spec %@ is not an ASLayoutElement!", child, self);
_childrenArray[i] = child;
i += 1;
}
#endif
[_childrenArray setArray:children];
}
- (nullable NSArray<id<ASLayoutElement>> *)children
@ -291,7 +289,9 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__)
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
{
NSArray *children = self.children;
NSMutableArray *sublayouts = [NSMutableArray arrayWithCapacity:children.count];
let count = children.count;
ASLayout *rawSublayouts[count];
int i = 0;
CGSize size = constrainedSize.min;
for (id<ASLayoutElement> child in children) {
@ -301,9 +301,9 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__)
size.width = MAX(size.width, sublayout.size.width);
size.height = MAX(size.height, sublayout.size.height);
[sublayouts addObject:sublayout];
rawSublayouts[i++] = sublayout;
}
let sublayouts = [NSArray<ASLayout *> arrayByTransferring:rawSublayouts count:i];
return [ASLayout layoutWithLayoutElement:self size:size sublayouts:sublayouts];
}

View File

@ -10,6 +10,7 @@
#import <AsyncDisplayKit/ASOverlayLayoutSpec.h>
#import <AsyncDisplayKit/ASLayoutSpec+Subclasses.h>
#import <AsyncDisplayKit/ASAssert.h>
#import <AsyncDisplayKit/ASCollections.h>
static NSUInteger const kUnderlayChildIndex = 0;
static NSUInteger const kOverlayChildIndex = 1;
@ -70,14 +71,17 @@ static NSUInteger const kOverlayChildIndex = 1;
{
ASLayout *contentsLayout = [self.child layoutThatFits:constrainedSize parentSize:parentSize];
contentsLayout.position = CGPointZero;
NSMutableArray *sublayouts = [NSMutableArray arrayWithObject:contentsLayout];
ASLayout *rawSublayouts[2];
int i = 0;
rawSublayouts[i++] = contentsLayout;
if (self.overlay) {
ASLayout *overlayLayout = [self.overlay layoutThatFits:ASSizeRangeMake(contentsLayout.size)
parentSize:contentsLayout.size];
overlayLayout.position = CGPointZero;
[sublayouts addObject:overlayLayout];
rawSublayouts[i++] = overlayLayout;
}
let sublayouts = [NSArray<ASLayout *> arrayByTransferring:rawSublayouts count:i];
return [ASLayout layoutWithLayoutElement:self size:contentsLayout.size sublayouts:sublayouts];
}

View File

@ -12,6 +12,7 @@
#import <numeric>
#import <vector>
#import <AsyncDisplayKit/ASCollections.h>
#import <AsyncDisplayKit/ASDimension.h>
#import <AsyncDisplayKit/ASLayout.h>
#import <AsyncDisplayKit/ASLayoutElement.h>
@ -151,12 +152,14 @@
self.style.ascender = stackChildren.front().style.ascender;
self.style.descender = stackChildren.back().style.descender;
}
const auto sublayouts = [[NSMutableArray<ASLayout *> alloc] init];
ASLayout *rawSublayouts[positionedLayout.items.size()];
int i = 0;
for (const auto &item : positionedLayout.items) {
[sublayouts addObject:item.layout];
rawSublayouts[i++] = item.layout;
}
let sublayouts = [NSArray<ASLayout *> arrayByTransferring:rawSublayouts count:i];
return [ASLayout layoutWithLayoutElement:self size:positionedLayout.size sublayouts:sublayouts];
}