4

I have an iPhone/iPad app which uses Core Data.

In my DB I have only one table, though it's a very large one (about 40 columns). When i build the DB i create and insert about 13,000 new entities, and then I call 'saveContext'.

for (NSArray *singleDiamond in allDiamonds)
{
     @try 
     {
         if (//Some validation)
         {
             Diamond *diamond = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([Diamond class]) 
                                                              inManagedObjectContext:self.managedObjectContext];
             //Do setup for diamond...
         }
     }
     @catch (NSException *exception) {NSLog(@"%@",[exception message]);}
 }
NSLog(@"Start Saving Context...");
[self saveContext];
NSLog(@"End Saving Context...");

My problem id that only the 'saveContext' method, takes 23 seconds to execute. That's not acceptable.

Is there something I do wrong? How can I improve the performance here?

Avi Shukron
  • 6,088
  • 8
  • 50
  • 84
  • Please give me idea or suggestion to insert every 100 objects in core data with batch insert for fast performance because In my iPad device, I have more than 6000 contacts and insert in core data with best performance so please help me for solve this issue. – Nikunj Jadav Jun 28 '13 at 06:24
  • Similar question with Swift example of batch inserting http://stackoverflow.com/questions/32034100/memory-leak-with-large-core-data-batch-insert-in-swift – Suragch Aug 16 '15 at 10:58

2 Answers2

4

You should call saveContext several times during the batch insert, and then call reset to "forget" the previous inserted managed objects. For example in my case I save the context every 100 objects. Moreover you should create a dedicated context for the import and optimize it (by setting the undomanager to nil, since you don't need to roolback/undo the whole insert). Read here: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdImporting.html

daveoncode
  • 18,900
  • 15
  • 104
  • 159
  • Well, i did try to save every "n" items, but I didn't get any significant improvement over saving everything at the end of the process. I tried n {0 , 100 ,1000 , 5000} – Avi Shukron Nov 15 '11 at 11:29
  • @daveoncode Please give me idea or suggestion to insert every 100 objects in core data with batch insert for fast performance because In my iPad device, I have more than 6000 contacts and insert in core data with best performance so please help me for solve this issue. – Nikunj Jadav Jun 28 '13 at 06:25
  • Calling reset had a minimally negative performance impact for me. The best scenario I found was saving every 100 records with no reset. – Tristan Warner-Smith Sep 17 '13 at 14:10
4

Saving 13.000 items is going to take a while.

Are the 13.000 items only saved when you first start the app, if so why not just supply the database as a payload with the app. So that when the database isn't already there just copy the one from the bundle.

rckoenes
  • 69,092
  • 8
  • 134
  • 166
  • I cant. I'm getting a CSV from the internet and i'm building the DB with it. – Avi Shukron Nov 15 '11 at 10:42
  • 1
    @rckoenes Please give me idea or suggestion to insert every 100 objects in core data with batch insert for fast performance because In my iPad device, I have more than 6000 contacts and insert in core data with best performance so please help me for solve this issue. – Nikunj Jadav Jun 28 '13 at 06:25
  • @NikunjR.Jadav You should post your own question, not request code in an answer to other question. – rckoenes Jul 01 '13 at 08:24