2012-10-12 82 views
0

我有一個PhoneGap移動應用程序,我需要生成一個匹配組合數組。在JavaScript方面,當生成組合的數組比較大時,代碼很快就會掛起。所以,我想我會製作一個插件來生成組合,將javascript對象數組傳遞到本機端並將其循環。Objective-C vs JavaScript循環性能

令我驚訝的是,下面的代碼在150 ms(JavaScript)中執行,而在本機端(Objective-C)則需要〜1000 ms。

有沒有人知道加快執行時間的任何提示?當球員超過10人時,即球隊陣容的長度等於252,這確實緩慢。上述執行時間適用於10名球員/ 252支球隊。

這裏的JavaScript代碼:

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 
        }); 
       } 
      } 
} 

...這是本機代碼:

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]; 
      } 
     } 
} 

...有問題的陣列(GAME.teams)看起來是這樣的:

{ 
    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; 
}, 

回答

2

通常當您遇到性能問題時,您應該使用Time Profiler工具來分析您的應用程序。

在這種情況下,我可以看到一些可能的問題。

首先,你在你的內部循環這樣做:

[t insertObject:[teams objectAtIndex:i] atIndex:0]; 
[t insertObject:[teams objectAtIndex:j] atIndex:1]; 

你只是在你的t對象的開頭插入越來越多的對象。你永遠不會清空它。我很確定那不是你想要的,這也可能是一個性能問題。

其次,您不必要地發送大量消息。例如,您正在提取掩碼O(N )次。你可以通過提取所有的蒙版一次來優化這個。

NSArray *teams = [options objectForKey:@"teams"]; 
NSUInteger teamCount = teams.count; 

int masks[teamCount]; 
for (NSUInteger i = 0; i < teamCount; ++i) { 
    masks[i] = [[teams[i] objectForKey:@"mask"] intValue]; 
} 

NSMutableArray *matches = [[NSMutableArray alloc] init]; 

for (NSUInteger i = 0; i < teamCount; ++i) { 
    for (NSUInteger j = i + 1; j < teamCount; ++j) { 
     if ((masks[i] & masks[j]) == 0) { 
      [matches addObject:@[teams[i], teams[j]]]; 
     } 
    } 
} 

你還在做O(N )迭代,但是你做的每一次迭代中少了很多的工作。

+0

感謝快速反應......不過,我得到這些線路上的多個錯誤:'口罩[我] = [[teams [i] objectForKey:@「mask」] intValue];'和'[matches addObject:@ [teams [i],teams [j]]];' – micadelli

+0

這些行使用新的Objective-C腳本在Xcode 4.4和4.5中添加語法。您需要升級Xcode,或更改這些行以使用'objectAtIndex:'而不是使用下標。 –

1

有一點要注意的是,

[t insertObject:[teams objectAtIndex:i] atIndex:0]; 

導致所有在t的元件,但每次使用時被移位。這可能會顯着減慢速度,因爲你在循環中做了兩次。使用[t addObject: ...]可能會更好。

此外,NSMutableArray可能會不必要地調整大小。如果你知道大概怎麼會大量需要是,你可以用一個特定的容量初始化:

NSMutableArray *t = [[NSMutableArray alloc] initWithCapacity: size];