Skip to content

Instantly share code, notes, and snippets.

@tadeuzagallo
Created May 6, 2015 17:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tadeuzagallo/04ee3ac7017cc4e1bc8e to your computer and use it in GitHub Desktop.
Save tadeuzagallo/04ee3ac7017cc4e1bc8e to your computer and use it in GitHub Desktop.
- (void)testJavaScriptCallSpeed
{
int const runs = 4e5;
int const frequency = 10;
double const threshold = 0.1;
static double const expectedTimes[] = {
0x1.469c0a1af80e3p+14,
0x1.5cb66713b13b1p+14,
0x1.593e1e9f7248p+14,
0x1.5d5f559066c1p+14,
};
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
RCTContextExecutor *executor = RCTCreateExecutor([RCTContextExecutor class]);
NSString *script = @" \
var modules = { \
module: { \
method: function () { \
return true; \
} \
} \
}; \
function require(module) { \
return modules[module]; \
} \
";
[executor executeApplicationScript:script sourceURL:[NSURL URLWithString:@"http://localhost:8081/"] onComplete:^(NSError *error) {
NSMutableArray *params = [[NSMutableArray alloc] init];
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 executeJSCall:@"module"
method:@"method"
arguments:params
context:RCTGetExecutorID(executor)
callback:^(id json, NSError *__error) {
RCTAssert([json isEqual:@YES], @"Invalid return");
}];
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);
}
STAssertTrue(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]];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment