Speed up Flipper by using background queue for serialization

Reviewed By: jknoxville

Differential Revision: D21290732

fbshipit-source-id: 21fcb793900a6517d764fa3a581255fd75a39801
This commit is contained in:
Adam Ernst
2020-04-28 21:30:31 -07:00
committed by Facebook GitHub Bot
parent b483e0688d
commit c62760b3e8
3 changed files with 46 additions and 1 deletions

View File

@@ -10,6 +10,7 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <FlipperKit/FlipperPlugin.h> #import <FlipperKit/FlipperPlugin.h>
#import <FlipperKit/SKMacros.h>
#import "SKDescriptorMapper.h" #import "SKDescriptorMapper.h"
#import "SKInvalidation.h" #import "SKInvalidation.h"
@@ -29,4 +30,7 @@
@end @end
/** Exposed for tests only. */
SK_EXTERN_C dispatch_queue_t SKLayoutPluginSerialBackgroundQueue(void);
#endif #endif

View File

@@ -258,7 +258,10 @@
[elements addObject:node]; [elements addObject:node];
} }
// Converting to folly::dynamic is expensive, do it on a bg queue:
dispatch_async(SKLayoutPluginSerialBackgroundQueue(), ^{
[responder success:@{@"elements" : elements}]; [responder success:@{@"elements" : elements}];
});
} }
- (void)onCallSetData:(NSString*)objectId - (void)onCallSetData:(NSString*)objectId
@@ -560,4 +563,22 @@
@end @end
/**
Operations like converting NSDictionary to folly::dynamic can be expensive.
Do them on this serial background queue to avoid blocking the main thread.
(Of course, ideally we wouldn't bother with building NSDictionary objects
in the first place, in favor of just using folly::dynamic directly...)
*/
dispatch_queue_t SKLayoutPluginSerialBackgroundQueue(void) {
static dispatch_queue_t queue;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
queue = dispatch_queue_create("flipper.layout.bg", DISPATCH_QUEUE_SERIAL);
// This should be relatively high priority, to prevent Flipper lag.
dispatch_set_target_queue(
queue, dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0));
});
return queue;
}
#endif #endif

View File

@@ -67,6 +67,11 @@
SonarReceiver receiver = connection.receivers[@"getNodes"]; SonarReceiver receiver = connection.receivers[@"getNodes"];
receiver(@{@"ids" : @[]}, responder); receiver(@{@"ids" : @[]}, responder);
dispatch_barrier_sync(
SKLayoutPluginSerialBackgroundQueue(),
^{
});
XCTAssertTrue(([responder.successes containsObject:@{@"elements" : @[]}])); XCTAssertTrue(([responder.successes containsObject:@{@"elements" : @[]}]));
} }
@@ -96,6 +101,11 @@
receiver( receiver(
@{@"ids" : @[ @"testNode1", @"testNode2", @"testNode3" ]}, responder); @{@"ids" : @[ @"testNode1", @"testNode2", @"testNode3" ]}, responder);
dispatch_barrier_sync(
SKLayoutPluginSerialBackgroundQueue(),
^{
});
XCTAssertTrue(([responder.successes containsObject:@{ XCTAssertTrue(([responder.successes containsObject:@{
@"elements" : @[ @"elements" : @[
@{ @{
@@ -149,6 +159,11 @@
SonarReceiver getNodesCall = connection.receivers[@"getNodes"]; SonarReceiver getNodesCall = connection.receivers[@"getNodes"];
getNodesCall(@{@"ids" : @[ @"testNode1", @"testNode2" ]}, responder); getNodesCall(@{@"ids" : @[ @"testNode1", @"testNode2" ]}, responder);
dispatch_barrier_sync(
SKLayoutPluginSerialBackgroundQueue(),
^{
});
SonarReceiver setHighlighted = connection.receivers[@"setHighlighted"]; SonarReceiver setHighlighted = connection.receivers[@"setHighlighted"];
setHighlighted(@{@"id" : @"testNode2"}, responder); setHighlighted(@{@"id" : @"testNode2"}, responder);
@@ -249,6 +264,11 @@
connection.receivers[@"getRoot"](@{}, responder); connection.receivers[@"getRoot"](@{}, responder);
connection.receivers[@"getNodes"](@{@"ids" : @[ @"testNode2" ]}, responder); connection.receivers[@"getNodes"](@{@"ids" : @[ @"testNode2" ]}, responder);
dispatch_barrier_sync(
SKLayoutPluginSerialBackgroundQueue(),
^{
});
// Modify the name of testNode3 // Modify the name of testNode3
connection.receivers[@"setData"]( connection.receivers[@"setData"](
@{ @{