From 3e2a3ca466a573ea5a361cee8eda787891f5e001 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Tue, 19 Apr 2016 11:36:54 -0700 Subject: [PATCH] Move RCTJSCExecutorTests to ReactKitBenchmarks Reviewed By: jspahrsummers Differential Revision: D3192966 fb-gh-sync-id: 2c0caef1217545a131396326546d610e345db597 fbshipit-source-id: 2c0caef1217545a131396326546d610e345db597 --- .../UIExplorerUnitTests/RCTJSCExecutorTests.m | 162 ------------------ 1 file changed, 162 deletions(-) diff --git a/Examples/UIExplorer/UIExplorerUnitTests/RCTJSCExecutorTests.m b/Examples/UIExplorer/UIExplorerUnitTests/RCTJSCExecutorTests.m index 5d08f8f46..c1404d4e0 100644 --- a/Examples/UIExplorer/UIExplorerUnitTests/RCTJSCExecutorTests.m +++ b/Examples/UIExplorer/UIExplorerUnitTests/RCTJSCExecutorTests.m @@ -19,8 +19,6 @@ #import "RCTJSCExecutor.h" #import "RCTUtils.h" -#define RUN_PERF_TESTS 0 - @interface RCTJSCExecutorTests : XCTestCase @end @@ -49,164 +47,4 @@ [_executor invalidate]; } -#if RUN_PERF_TESTS - -static uint64_t _get_time_nanoseconds(void) -{ - static struct mach_timebase_info tb_info = {0, 0}; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - int ret = mach_timebase_info(&tb_info); - assert(0 == ret); - }); - - return (mach_absolute_time() * tb_info.numer) / tb_info.denom; -} - -- (void)testDeserializationPerf -{ - // This test case checks the assumption that deserializing objects from JavaScript - // values one-by-one via ObjC JSC API is slower than using JSON string - // You might want to switch your tests schema to "Release" build configuration - - JSContextGroupRef group = JSContextGroupCreate(); - JSGlobalContextRef context = JSGlobalContextCreateInGroup(group, NULL); - id message = @[@[@1, @2, @3, @4], @[@{@"a": @1}, @{@"b": @2}], (id)kCFNull]; - NSString *code = RCTJSONStringify(message, NULL); - JSStringRef script = JSStringCreateWithCFString((__bridge CFStringRef)code); - JSValueRef error = NULL; - JSValueRef value = JSEvaluateScript(context, script, NULL, NULL, 0, &error); - XCTAssertTrue(error == NULL); - - id obj; - uint64_t start = _get_time_nanoseconds(); - for (int i = 0; i < 10000; i++) { - JSStringRef jsonJSString = JSValueCreateJSONString(context, value, 0, nil); - NSString *jsonString = (__bridge NSString *)JSStringCopyCFString(kCFAllocatorDefault, jsonJSString); - JSStringRelease(jsonJSString); - - obj = RCTJSONParse(jsonString, NULL); - } - NSLog(@"JSON Parse time: %.2fms", (_get_time_nanoseconds() - start) / 1000000.0); - - JSStringRelease(script); - JSGlobalContextRelease(context); - JSContextGroupRelease(group); -} - -- (void)testJavaScriptCallSpeed -{ -/** - * Since we almost don't change the RCTJSCExecutor logic, and this test is - * very likely to become flaky (specially across different devices) leave it - * to be run manually - * - * Previous Values: If you change the executor code, you should update this values - */ - - int const runs = 4e5; - int const frequency = 10; - double const threshold = 0.1; - static double const expectedTimes[] = { - 0x1.6199943826cf1p+13, - 0x1.a3bc0a81551c3p+13, - 0x1.d49fbb8602fe3p+13, - 0x1.d1f64085ecb7bp+13, - }; - - dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); - NSString *script = @" \ - var modules = { \ - module: { \ - method: function () { \ - return true; \ - } \ - } \ - }; \ - var Bridge = { \ - callFunctionReturnFlushedQueue: function(module, method, args) { \ - modules[module].apply(modules[module], args); \ - } \ - }; \ - function require(module) { \ - return Bridge; \ - } \ - "; - - [_executor executeApplicationScript:[script dataUsingEncoding:NSUTF8StringEncoding] sourceURL:[NSURL URLWithString:@"http://localhost:8081/"] onComplete:^(__unused NSError *error) { - NSMutableArray *params = [NSMutableArray new]; - id data = @1; - for (int i = 0; i < 4; i++) { - double samples[runs / frequency]; - int size = runs / frequency; - double total = 0; - for (int j = 0; j < runs; j++) { - @autoreleasepool { - double start = _get_time_nanoseconds(); - [_executor callFunctionOnModule:@"module" - method:@"method" - arguments:params - callback:^(__unused id json, __unused NSError *unused) { - }]; - double run = _get_time_nanoseconds() - start; - if ((j % frequency) == frequency - 1) { // Warmup - total += run; - samples[j/frequency] = run; - } - } - } - - double mean = total / size; - double variance = 0; - - for (int j = 0; j < size; j++) { - variance += pow(samples[j] - mean, 2); - } - variance /= size; - - double standardDeviation = sqrt(variance); - double marginOfError = standardDeviation * 1.645; - - double lower = mean - marginOfError; - double upper = mean + marginOfError; - - int s = 0; - total = 0; - for (int j = 0; j < size; j++) { - double v = samples[j]; - if (v >= lower && v <= upper) { - samples[s++] = v; - total += v; - } - } - mean = total / s; - - lower = mean * (1.0 - threshold); - upper = mean * (1.0 + threshold); - - double expected = expectedTimes[i]; - - NSLog(@"Previous: %lf, New: %f -> %a", expected, mean, mean); - if (upper < expected) { - NSLog(@"You made JS calls with %d argument(s) %.2lf%% faster :) - Remember to update the tests with the new value: %a", - i, (1 - (double)mean / expected) * 100, mean); - } - - - XCTAssertTrue(lower < expected, @"You made JS calls with %d argument(s) %.2lf%% slower :( - If that's *really* necessary, update the tests with the new value: %a", - i, ((double)mean / expected - 1) * 100, mean); - - [params addObject:data]; - } - dispatch_semaphore_signal(semaphore); - }]; - - while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW)) { - [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode - beforeDate:[NSDate dateWithTimeIntervalSinceNow:10]]; - } -} - -#endif - @end