I have a PhoneGap mobile application that I need to generate an array of match combinations. In JavaScript side, the code hanged pretty soon when the array of which the combinations are generated from got a bit bigger. So, I thought I’ll make a plugin to generate the combinations, passing the array of javascript objects to native side and loop it there.
To my surprise the following codes executes in 150 ms (JavaScript) whereas in native side (Objective-C) it takes ~1000 ms.
Does anyone know any tips for speeding up those executing times? When players exceeds 10, i.e. the length of the array of teams equals 252 it really gets slow. Those execution times mentioned above are for 10 players / 252 teams.
Here’s the JavaScript code:
for (i = 0; i < GAME.teams.length; i += 1) {
for (j = i + 1; j < GAME.teams.length; j += 1) {
t1 = GAME.teams[i];
t2 = GAME.teams[j];
if ((t1.mask & t2.mask) === 0) {
GAME.matches.push({
Team1: t1,
Team2: t2
});
}
}
}
… and here’s the native code:
NSArray *teams = [[NSArray alloc] initWithArray: [options objectForKey:@"teams"]];
NSMutableArray *t = [[NSMutableArray alloc] init];
int mask_t1;
int mask_t2;
for (NSInteger i = 0; i < [teams count]; i++) {
for (NSInteger j = i + 1; j < [teams count]; j++) {
mask_t1 = [[[teams objectAtIndex:i] objectForKey:@"mask"] intValue];
mask_t2 = [[[teams objectAtIndex:j] objectForKey:@"mask"] intValue];
if ((mask_t1 & mask_t2) == 0) {
[t insertObject:[teams objectAtIndex:i] atIndex:0];
[t insertObject:[teams objectAtIndex:j] atIndex:1];
/*
NSArray *newCombination = [[NSArray alloc] initWithObjects:
[teams objectAtIndex:i],
[teams objectAtIndex:j],
nil];
*/
[combinations addObject:t];
}
}
}
… the array in question (GAME.teams) looks like this:
{
count = 2;
full = 1;
list = (
{
index = 0;
mask = 1;
name = A;
score = 0;
},
{
index = 1;
mask = 2;
name = B;
score = 0;
}
);
mask = 3;
name = A;
},
{
count = 2;
full = 1;
list = (
{
index = 0;
mask = 1;
name = A;
score = 0;
},
{
index = 2;
mask = 4;
name = C;
score = 0;
}
);
mask = 5;
name = A;
},
Generally when you have a performance problem, you should profile your app using the Time Profiler instrument.
In this case, I can see some likely problems.
First of all, you’re doing this in your inner loop:
You’re just inserting more and more objects at the beginning of your
tobject. You’re never emptying it out. I’m pretty sure that’s not what you want, and it’s probably a performance problem too.Second, you’re sending a lot of messages unnecessarily. For example, you’re extracting masks O(N2) times. You can optimize this by extracting all of the masks once.
You’re still doing O(N2) iterations, but you’re doing a lot less work on each iteration.