Skip to content
This repository has been archived by the owner on Feb 18, 2019. It is now read-only.

Commit

Permalink
Add more performance logs and improve Systrace support
Browse files Browse the repository at this point in the history
Reviewed By: tadeuzagallo

Differential Revision: D3040998

fb-gh-sync-id: c5ab4e5bcc073f94a2d309bfa7698919cf7e8856
shipit-source-id: c5ab4e5bcc073f94a2d309bfa7698919cf7e8856
  • Loading branch information
alexeylang authored and Facebook Github Bot 6 committed Mar 15, 2016
1 parent f87b673 commit f6853b8
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 15 deletions.
14 changes: 8 additions & 6 deletions React/Base/RCTBatchedBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ - (void)start

// Asynchronously initialize the JS executor
dispatch_group_async(setupJSExecutorAndModuleConfig, bridgeQueue, ^{
RCTPerformanceLoggerStart(RCTPLJSCExecutorSetup);
[weakSelf setUpExecutor];
RCTPerformanceLoggerEnd(RCTPLJSCExecutorSetup);
});

// Asynchronously gather the module config
Expand Down Expand Up @@ -171,13 +173,8 @@ - (void)start
- (void)loadSource:(RCTSourceLoadBlock)_onSourceLoad
{
RCTPerformanceLoggerStart(RCTPLScriptDownload);
NSUInteger cookie = RCTProfileBeginAsyncEvent(0, @"JavaScript download", nil);

// Suppress a warning if RCTProfileBeginAsyncEvent gets compiled out
(void)cookie;

RCTSourceLoadBlock onSourceLoad = ^(NSError *error, NSData *source) {
RCTProfileEndAsyncEvent(0, @"native", cookie, @"JavaScript download", @"JS async", nil);
RCTPerformanceLoggerEnd(RCTPLScriptDownload);

_onSourceLoad(error, source);
Expand Down Expand Up @@ -332,7 +329,7 @@ - (void)initModulesWithDispatchGroup:(dispatch_group_t)dispatchGroup
moduleClass, moduleName, moduleData.moduleClass);
}
}

// Instantiate moduleData (TODO: can we defer this until config generation?)
moduleData = [[RCTModuleData alloc] initWithModuleClass:moduleClass
bridge:self];
Expand Down Expand Up @@ -366,6 +363,7 @@ - (void)initModulesWithDispatchGroup:(dispatch_group_t)dispatchGroup
_moduleSetupComplete = YES;

// Set up modules that require main thread init or constants export
RCTPerformanceLoggerSet(RCTPLNativeModuleMainThread, 0);
for (RCTModuleData *moduleData in _moduleDataByID) {
__weak RCTBatchedBridge *weakSelf = self;
if (moduleData.requiresMainThreadSetup) {
Expand All @@ -376,8 +374,10 @@ - (void)initModulesWithDispatchGroup:(dispatch_group_t)dispatchGroup
// they will already be available before they are ever required.
dispatch_group_async(dispatchGroup, dispatch_get_main_queue(), ^{
if (weakSelf.valid) {
RCTPerformanceLoggerAppendStart(RCTPLNativeModuleMainThread);
(void)[moduleData instance];
[moduleData gatherConstants];
RCTPerformanceLoggerAppendEnd(RCTPLNativeModuleMainThread);
}
});
} else if (moduleData.hasConstantsToExport) {
Expand All @@ -386,7 +386,9 @@ - (void)initModulesWithDispatchGroup:(dispatch_group_t)dispatchGroup
(void)[moduleData instance];
dispatch_group_async(dispatchGroup, dispatch_get_main_queue(), ^{
if (weakSelf.valid) {
RCTPerformanceLoggerAppendStart(RCTPLNativeModuleMainThread);
[moduleData gatherConstants];
RCTPerformanceLoggerAppendEnd(RCTPLNativeModuleMainThread);
}
});
}
Expand Down
3 changes: 3 additions & 0 deletions React/Base/RCTModuleData.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#import "RCTBridge+Private.h"
#import "RCTModuleMethod.h"
#import "RCTLog.h"
#import "RCTProfile.h"
#import "RCTUtils.h"

@implementation RCTModuleData
Expand Down Expand Up @@ -185,6 +186,7 @@ - (BOOL)hasInstance
- (id<RCTBridgeModule>)instance
{
if (!_setupComplete) {
RCT_PROFILE_BEGIN_EVENT(0, [NSString stringWithFormat:@"[RCTModuleData instanceForClass:%@]", _moduleClass], nil);
if (_requiresMainThreadSetup) {
// The chances of deadlock here are low, because module init very rarely
// calls out to other threads, however we can't control when a module might
Expand All @@ -196,6 +198,7 @@ - (BOOL)hasInstance
} else {
[self setUpInstanceAndBridge];
}
RCT_PROFILE_END_EVENT(0, @"", nil);
}
return _instance;
}
Expand Down
33 changes: 33 additions & 0 deletions React/Base/RCTPerformanceLogger.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,48 @@ typedef NS_ENUM(NSUInteger, RCTPLTag) {
RCTPLScriptDownload = 0,
RCTPLScriptExecution,
RCTPLNativeModuleInit,
RCTPLNativeModuleMainThread,
RCTPLNativeModulePrepareConfig,
RCTPLNativeModuleInjectConfig,
RCTPLJSCExecutorSetup,
RCTPLTTI,
RCTPLBundleSize,
RCTPLSize
};

/**
* Starts measuring a metric with the given tag.
* Overrides previous value if the measurement has been already started.
* If RCTProfile is enabled it also begins appropriate async event.
*/
RCT_EXTERN void RCTPerformanceLoggerStart(RCTPLTag tag);

/**
* Stops measuring a metric with given tag.
* Checks if RCTPerformanceLoggerStart() has been called before
* and doesn't do anything and log a message if it hasn't.
* If RCTProfile is enabled it also ends appropriate async event.
*/
RCT_EXTERN void RCTPerformanceLoggerEnd(RCTPLTag tag);

/**
* Sets given value for a metric with given tag.
*/
RCT_EXTERN void RCTPerformanceLoggerSet(RCTPLTag tag, int64_t value);

/**
* Starts an additional measurement for a metric with given tag.
* It doesn't override previous measurement, instead it'll append a new value
* to the old one.
*/
RCT_EXTERN void RCTPerformanceLoggerAppendStart(RCTPLTag tag);

/**
* Stops measurement and appends the result to the metric with given tag.
* Checks if RCTPerformanceLoggerAppendStart() has been called before
* and doesn't do anything and log a message if it hasn't.
*/
RCT_EXTERN void RCTPerformanceLoggerAppendEnd(RCTPLTag tag);

RCT_EXTERN NSArray<NSNumber *> *RCTPerformanceLoggerOutput(void);
RCT_EXTERN NSArray *RCTPerformanceLoggerLabels(void);
56 changes: 47 additions & 9 deletions React/Base/RCTPerformanceLogger.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@
#import "RCTPerformanceLogger.h"
#import "RCTRootView.h"
#import "RCTLog.h"
#import "RCTProfile.h"

static int64_t RCTPLData[RCTPLSize][2] = {};
static int64_t RCTPLCookies[RCTPLSize] = {};

void RCTPerformanceLoggerStart(RCTPLTag tag)
{
if (RCTProfileIsProfiling()) {
NSString *label = RCTPerformanceLoggerLabels()[tag];
RCTPLCookies[tag] = RCTProfileBeginAsyncEvent(0, label, nil);
}

RCTPLData[tag][0] = CACurrentMediaTime() * 1000;
RCTPLData[tag][1] = 0;
}
Expand All @@ -25,6 +32,11 @@ void RCTPerformanceLoggerEnd(RCTPLTag tag)
{
if (RCTPLData[tag][0] != 0 && RCTPLData[tag][1] == 0) {
RCTPLData[tag][1] = CACurrentMediaTime() * 1000;

if (RCTProfileIsProfiling()) {
NSString *label = RCTPerformanceLoggerLabels()[tag];
RCTProfileEndAsyncEvent(0, @"native", RCTPLCookies[tag], label, @"RCTPerformanceLogger", nil);
}
} else {
RCTLogInfo(@"Unbalanced calls start/end for tag %li", (unsigned long)tag);
}
Expand All @@ -36,6 +48,21 @@ void RCTPerformanceLoggerSet(RCTPLTag tag, int64_t value)
RCTPLData[tag][1] = value;
}

void RCTPerformanceLoggerAppendStart(RCTPLTag tag)
{
RCTPLData[tag][0] = CACurrentMediaTime() * 1000;
}

void RCTPerformanceLoggerAppendEnd(RCTPLTag tag)
{
if (RCTPLData[tag][0] != 0) {
RCTPLData[tag][1] += CACurrentMediaTime() * 1000 - RCTPLData[tag][0];
RCTPLData[tag][0] = 0;
} else {
RCTLogInfo(@"Unbalanced calls start/end for tag %li", (unsigned long)tag);
}
}

NSArray<NSNumber *> *RCTPerformanceLoggerOutput(void)
{
return @[
Expand All @@ -45,10 +72,14 @@ void RCTPerformanceLoggerSet(RCTPLTag tag, int64_t value)
@(RCTPLData[RCTPLScriptExecution][1]),
@(RCTPLData[RCTPLNativeModuleInit][0]),
@(RCTPLData[RCTPLNativeModuleInit][1]),
@(RCTPLData[RCTPLNativeModuleMainThread][0]),
@(RCTPLData[RCTPLNativeModuleMainThread][1]),
@(RCTPLData[RCTPLNativeModulePrepareConfig][0]),
@(RCTPLData[RCTPLNativeModulePrepareConfig][1]),
@(RCTPLData[RCTPLNativeModuleInjectConfig][0]),
@(RCTPLData[RCTPLNativeModuleInjectConfig][1]),
@(RCTPLData[RCTPLJSCExecutorSetup][0]),
@(RCTPLData[RCTPLJSCExecutorSetup][1]),
@(RCTPLData[RCTPLTTI][0]),
@(RCTPLData[RCTPLTTI][1]),
@(RCTPLData[RCTPLBundleSize][0]),
Expand All @@ -58,15 +89,22 @@ void RCTPerformanceLoggerSet(RCTPLTag tag, int64_t value)

NSArray *RCTPerformanceLoggerLabels(void)
{
return @[
@"ScriptDownload",
@"ScriptExecution",
@"NativeModuleInit",
@"NativeModulePrepareConfig",
@"NativeModuleInjectConfig",
@"TTI",
@"BundleSize",
];
static NSArray *labels;
static dispatch_once_t token;
dispatch_once(&token, ^{
labels = @[
@"ScriptDownload",
@"ScriptExecution",
@"NativeModuleInit",
@"NativeModuleMainThread",
@"NativeModulePrepareConfig",
@"NativeModuleInjectConfig",
@"JSCExecutorSetup",
@"RootViewTTI",
@"BundleSize",
];
});
return labels;
}

@interface RCTPerformanceLogger : NSObject <RCTBridgeModule>
Expand Down

0 comments on commit f6853b8

Please sign in to comment.