2014-06-10 209 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]; 
    }]; 
}