I was trying to add 200k messages to a core data object for a proof of concept of a twitter app. This works well and my entities are added. I have a UISearchBar and a UITableView to display these. However, for every new 1000 object, my time seems to be increasing exponentially. Is this normal ? I expected CoreData to perform well for huge datasets. Do you have better suggestion to handling such huge dataset. I wonder, how Dictionary apps work.
My Console Output is here:
-2012-03-26 22:19:28.126 TweetReader[3668:707] Done 1000
-2012-03-26 22:19:40.335 TweetReader[3668:707] Done 2000
-2012-03-26 22:19:55.136 TweetReader[3668:707] Done 3000
-2012-03-26 22:20:18.569 TweetReader[3668:707] Done 4000
-2012-03-26 22:20:50.166 TweetReader[3668:707] Done 5000
-2012-03-26 22:21:30.284 TweetReader[3668:707] Done 6000
-2012-03-26 22:22:19.096 TweetReader[3668:707] Done 7000
-2012-03-26 22:23:16.091 TweetReader[3668:707] Done 8000
-2012-03-26 22:24:21.321 TweetReader[3668:707] Done 9000
-2012-03-26 22:25:35.017 TweetReader[3668:707] Done 10000
-2012-03-26 22:26:57.250 TweetReader[3668:707] Done 11000
-2012-03-26 22:28:27.563 TweetReader[3668:707] Done 12000
-2012-03-26 22:30:06.202 TweetReader[3668:707] Done 13000
-2012-03-26 22:31:52.645 TweetReader[3668:707] Done 14000
Here it is my code to save into CoreData:
for (NSInteger i = 1; i <= 200000; i++) {
NSAutoreleasePool * myPool = [[NSAutoreleasePool alloc] init];
Tweet *tweetie = [NSEntityDescription insertNewObjectForEntityForName:@"Tweet" inManagedObjectContext:self.managedObjectContext];
tweetie.name = [NSString stringWithFormat:@"%10d",i];
tweetie.message =[NSString stringWithFormat:@"%10d",i];
// Save the context after 1000 objects.
if (! (i % 1000)) {
NSError *error;
NSLog(@"Done %d",i);
if (![managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
[myPool release];
}
}
Which columns do you have indexed on your database? Have you tried locking the context while you add to see if it can optimise this (i.e. do the inserts transactionally?)
Core Data is notoriously bad at bulk inserts. The solution to this might just be to use sqlite directly – see this article for a real life case study of someone who had to do that : http://inessential.com/2010/02/26/on_switching_away_from_core_data