[ASDataController] Use 2 Threads Per CPU When Measuring Nodes (#2145)

* [ASDataController] Use custom apply function to control thread count

* Relax the test for stupid Travis CI

* Remove unneeded import
This commit is contained in:
Adlai Holler
2016-08-26 10:54:55 -07:00
committed by GitHub
parent 480ba8c3fa
commit 6a482dc153
4 changed files with 80 additions and 1 deletions

View File

@@ -419,6 +419,8 @@
CC3B20901C3F892D00798563 /* ASBridgedPropertiesTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC3B208F1C3F892D00798563 /* ASBridgedPropertiesTests.mm */; };
CC4981B31D1A02BE004E13CC /* ASTableViewThrashTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4981B21D1A02BE004E13CC /* ASTableViewThrashTests.m */; };
CC4981BD1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4981BB1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m */; };
CC54A81C1D70079800296A24 /* ASDispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = CC54A81B1D70077A00296A24 /* ASDispatch.h */; };
CC54A81E1D7008B300296A24 /* ASDispatchTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC54A81D1D7008B300296A24 /* ASDispatchTests.m */; };
CC7FD9DF1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m */; };
CC7FD9E11BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9E01BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m */; };
CC7FD9E21BB603FF005CCB2B /* ASPhotosFrameworkImageRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -1090,6 +1092,8 @@
CC4981B21D1A02BE004E13CC /* ASTableViewThrashTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTableViewThrashTests.m; sourceTree = "<group>"; };
CC4981BA1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSIndexSet+ASHelpers.h"; sourceTree = "<group>"; };
CC4981BB1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSIndexSet+ASHelpers.m"; sourceTree = "<group>"; };
CC54A81B1D70077A00296A24 /* ASDispatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASDispatch.h; sourceTree = "<group>"; };
CC54A81D1D7008B300296A24 /* ASDispatchTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDispatchTests.m; sourceTree = "<group>"; };
CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPhotosFrameworkImageRequest.h; sourceTree = "<group>"; };
CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPhotosFrameworkImageRequest.m; sourceTree = "<group>"; };
CC7FD9E01BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPhotosFrameworkImageRequestTests.m; sourceTree = "<group>"; };
@@ -1328,6 +1332,7 @@
058D09C5195D04C000B7D73C /* AsyncDisplayKitTests */ = {
isa = PBXGroup;
children = (
CC54A81D1D7008B300296A24 /* ASDispatchTests.m */,
CCA221D21D6FA7EF00AF6A0F /* ASViewControllerTests.m */,
CC0AEEA31D66316E005D1C78 /* ASUICollectionViewTests.m */,
CCB2F34C1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.m */,
@@ -1481,6 +1486,7 @@
058D0A01195D050800B7D73C /* Private */ = {
isa = PBXGroup;
children = (
CC54A81B1D70077A00296A24 /* ASDispatch.h */,
058D0A02195D050800B7D73C /* _AS-objc-internal.h */,
058D0A03195D050800B7D73C /* _ASCoreAnimationExtras.h */,
058D0A04195D050800B7D73C /* _ASCoreAnimationExtras.mm */,
@@ -1706,6 +1712,7 @@
B35062111B010EFD0018CF92 /* _ASDisplayView.h in Headers */,
68EE0DBE1C1B4ED300BA1B99 /* ASMainSerialQueue.h in Headers */,
B350624B1B010EFD0018CF92 /* _ASPendingState.h in Headers */,
CC54A81C1D70079800296A24 /* ASDispatch.h in Headers */,
9C55866C1BD54A3000B50E3A /* ASAsciiArtBoxCreator.h in Headers */,
B350624D1B010EFD0018CF92 /* _ASScopeTimer.h in Headers */,
254C6B771BF94DF4003EC431 /* ASTextKitAttributes.h in Headers */,
@@ -2195,6 +2202,7 @@
058D0A3A195D057000B7D73C /* ASDisplayNodeTests.m in Sources */,
696FCB311D6E46050093471E /* ASBackgroundLayoutSpecSnapshotTests.mm in Sources */,
CC4981B31D1A02BE004E13CC /* ASTableViewThrashTests.m in Sources */,
CC54A81E1D7008B300296A24 /* ASDispatchTests.m in Sources */,
058D0A3B195D057000B7D73C /* ASDisplayNodeTestsHelper.m in Sources */,
83A7D95E1D446A6E00BF333E /* ASWeakMapTests.m in Sources */,
056D21551ABCEF50001107EF /* ASImageNodeSnapshotTests.m in Sources */,

View File

@@ -19,6 +19,7 @@
#import "ASThread.h"
#import "ASIndexedNodeContext.h"
#import "ASDataController+Subclasses.h"
#import "ASDispatch.h"
//#define LOG(...) NSLog(__VA_ARGS__)
#define LOG(...)
@@ -183,7 +184,7 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
__strong ASCellNode **allocatedNodeBuffer = (__strong ASCellNode **)calloc(nodeCount, sizeof(ASCellNode *));
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(nodeCount, queue, ^(size_t i) {
ASDispatchApply(nodeCount, queue, 0, ^(size_t i) {
RETURN_IF_NO_DATASOURCE();
// Allocate the node.

View File

@@ -0,0 +1,32 @@
//
// ASDispatch.h
// AsyncDisplayKit
//
// Created by Adlai Holler on 8/25/16.
// Copyright © 2016 Facebook. All rights reserved.
//
#import <Foundation/Foundation.h>
/**
* Like dispatch_apply, but you can set the thread count. 0 means 2*active CPUs.
*
* Note: The actual number of threads may be lower than threadCount, if libdispatch
* decides the system can't handle it. In reality this rarely happens.
*/
static void ASDispatchApply(size_t iterationCount, dispatch_queue_t queue, NSUInteger threadCount, void(^work)(size_t i)) {
if (threadCount == 0) {
threadCount = [NSProcessInfo processInfo].activeProcessorCount * 2;
}
dispatch_group_t group = dispatch_group_create();
__block size_t trueI = 0;
for (NSUInteger t = 0; t < threadCount; t++) {
dispatch_group_async(group, queue, ^{
size_t i;
while ((i = __sync_fetch_and_add(&trueI, 1)) < iterationCount) {
work(i);
}
});
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
};

View File

@@ -0,0 +1,38 @@
//
// ASDispatchTests.m
// AsyncDisplayKit
//
// Created by Adlai Holler on 8/25/16.
// Copyright © 2016 Facebook. All rights reserved.
//
#import <XCTest/XCTest.h>
#import "ASDispatch.h"
@interface ASDispatchTests : XCTestCase
@end
@implementation ASDispatchTests
- (void)testDispatchApply
{
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSInteger expectedThreadCount = [NSProcessInfo processInfo].activeProcessorCount * 2;
NSLock *lock = [NSLock new];
NSMutableSet *threads = [NSMutableSet set];
NSMutableIndexSet *indices = [NSMutableIndexSet indexSet];
size_t const iterations = 1E5;
ASDispatchApply(iterations, q, 0, ^(size_t i) {
[lock lock];
[threads addObject:[NSThread currentThread]];
XCTAssertFalse([indices containsIndex:i]);
[indices addIndex:i];
[lock unlock];
});
XCTAssertLessThanOrEqual(threads.count, expectedThreadCount);
XCTAssertEqualObjects(indices, [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, iterations)]);
}
@end