2014-06-10 263 views
0

有沒有什麼辦法可以優化數組中的循環?我在數組[arr]中有10,000個對象,所以循環將繼續10k倍,我必須在CfgBarCodeMask和CfgBarCodeMaskDetails之間建立關係。大約需要8分鐘。如何減少這個時間?循環優化/ CoreData優化

NSArray *arr=[coreDataEngine fetchObjectWithEntityName:@"CfgBarCodeMask" withPredicate:nil withSortDescriptor:nil error:nil ]; 
NSString *predicateString = [NSString stringWithFormat:@"barCodeMaskId == $idVar"]; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString]; 

[arr enumerateObjectsUsingBlock:^(CfgBarCodeMask *barcodeMask, NSUInteger idx, BOOL *stop) 
{     
    NSDictionary *variables = @{ @"idVar" : barcodeMask.id1 }; 

    NSArray *destinationArray= 
     [coreDataEngine fetchObjectWithEntityName:@"CfgBarCodeMaskDetail" 
            withPredicate:[predicate predicateWithSubstitutionVariables:variables] 
           withSortDescriptor:nil error:nil ]; 

    if ([destinationArray count] >0) { 
     [barcodeMask addMaskDetails:[NSSet setWithArray:destinationArray]]; 
    }   
}]; 
+0

第一步:使用儀器獲取的線索關於你的代碼的一部分消耗大部分的時間 –

+1

看起來你正在尋找一個「加盟」讓核心數據爲你做匹配。也許這有助於:http://stackoverflow.com/questions/2458245/iphone-coredata-join –

回答

1

您可以使用將循環分成多個批次。每批處理大約2000個對象,並使用併發的NSManagedObjectContext來並行執行所有補丁。這是我從另一個數據庫遷移600K對象時所做的。

+1

聽起來不錯.. !!!但你能提供一些代碼片段嗎? –

0

我想你應該有這樣的事情

// Create concurency managed object context in your core data engine 
_managedObject = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 
[_managedObject setPersistentStoreCoordinator:_psCoordinator]; 
[_managedObject setUndoManager:nil]; 


// Batch1 
NSPredicate *predicate = //create predicate to get object 1-2000 
NSArray *arr=[coreDataEngine fetchObjectWithEntityName:@"CfgBarCodeMask" withPredicate:predicate withSortDescriptor:nil error:nil]; 
[self processObjects:arr]; 

// Batch2 
predicate = //create predicate to get object 2000-4000 
arr=[coreDataEngine fetchObjectWithEntityName:@"CfgBarCodeMask" withPredicate:predicate withSortDescriptor:nil error:nil]; 
[self processObjects:arr]; 

// Batch3 
predicate = //create predicate to get object 4000-6000 
arr=[coreDataEngine fetchObjectWithEntityName:@"CfgBarCodeMask" withPredicate:predicate withSortDescriptor:nil error:nil]; 
[self processObjects:arr]; 

// Batch4 
predicate = //create predicate to get object 6K-8K 
arr=[coreDataEngine fetchObjectWithEntityName:@"CfgBarCodeMask" withPredicate:predicate withSortDescriptor:nil error:nil]; 
[self processObjects:arr]; 

// Batch5 
predicate = //create predicate to get object 8K-10K 
arr=[coreDataEngine fetchObjectWithEntityName:@"CfgBarCodeMask" withPredicate:predicate withSortDescriptor:nil error:nil]; 
[self processObjects:arr]; 


(void)processObjects:(NSArray) objects 
{ 
    [_managedObject performBlock: { 
     NSString *predicateString = [NSString stringWithFormat:@"barCodeMaskId == $idVar"]; 
     NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString]; 
     [arr enumerateObjectsUsingBlock:^(CfgBarCodeMask *barcodeMask, NSUInteger idx, BOOL *stop) 
     {     
      NSDictionary *variables = @{ @"idVar" : barcodeMask.id1 }; 

      NSArray *destinationArray= 
       [coreDataEngine fetchObjectWithEntityName:@"CfgBarCodeMaskDetail" 
              withPredicate:[predicate predicateWithSubstitutionVariables:variables] 
             withSortDescriptor:nil error:nil ]; 

      if ([destinationArray count] >0) { 
       [barcodeMask addMaskDetails:[NSSet setWithArray:destinationArray]]; 
      }   
     }]; 
     [_managedObject save:nil]; 
    }]; 
}