I have an array with 36 rows which was fetched from CoreData. Each row has three attributes: podNumber, pieceNumber, and colorNumber.
What I want to do is shuffle the results in groups of six. Such that each pod has six pieces, and these will be shuffled for that group.
I am able to do this efficiently; however when I update the CoreData with the randomized values the performance is noticeably sluggish. I would say it takes a 1-1.5 seconds to complete the loop.
I experimented with two methods: 1) deleting the old array from CoreData and adding a new one 2) searching for the unique row in CD and updating
I found the first method is slightly faster. Does anyone have any insight as to how I could speed this up? Is there a more efficient way to update a large batch of core data. Do I need to make it a background process and how would that work.
Thanks.
MJ
Here is method one:
//Fetch them all and then delete them all
NSFetchRequest * fetchPieceColors = [[NSFetchRequest alloc] init];
[fetchPieceColors setEntity:[NSEntityDescription entityForName:@"PieceColors" inManagedObjectContext:managedObjectContext]];
[fetchPieceColors setPredicate:[NSPredicate predicateWithFormat:@"(game = %@)",games]];
[fetchPieceColors setIncludesPropertyValues:NO];
NSError * error = nil;
NSArray * pieceColor = [managedObjectContext executeFetchRequest:fetchPieceColors error:&error];
[fetchPieceColors release];
for (NSManagedObject * piece in pieceColor) {
[managedObjectContext deleteObject:piece];
}
NSError *saveError = nil;
[managedObjectContext save:&saveError];
//Add back
for (int b=0;b<6;b++) {
for (int j=0;j<6;j++) {
NSError *error;
NSManagedObject *fetchPieceColors = [NSEntityDescription
insertNewObjectForEntityForName:@"PieceColors"
inManagedObjectContext:managedObjectContext];
[fetchPieceColors setValue:[NSNumber numberWithInt:b] forKey:@"podNumber"];
[fetchPieceColors setValue:[NSNumber numberWithInt:j] forKey:@"pieceNumber"];
[fetchPieceColors setValue:[shuffledArray objectAtIndex:(b*6)+j] forKey:@"colorNumber"];
[fetchPieceColors setValue:games forKey:@"game"];
if (![managedObjectContext save:&error])
{
NSLog(@"Problem saving: %@", [error localizedDescription]);
}
}
}
As timthetoolman pointed out it is the IO of hitting the disk that is the killer. What you need to do is get all of the data in memory, make your edits and then save it all at once.
The Efficiently Importing Data of the
Core Data Programming Guidehas some useful hints on what you can do to improve performance.