views:

60

answers:

3

I'm trying to import a large amount of data into a core data store on the iPhone. I'm using a SQLite backing for the core data store. It seems to be taking way longer than I would expect it to. I've trimmed down the routines so that it is basically just attempting to a fetch an object (to see if it already exists) and then create a new object if it doesn't (they never do since I am importing data). The fetching isn't the time consuming part, though. It's the creation of the objects. Basically, the offending code is:

MobileObject *newObject = (MobileObject *)[NSEntityDescription insertNewObjectForEntityForName:objDesc inManagedObjectContext:managedObjectContext];

I've noticed that on the simulator, it is fairly quick at the start with about 100 objects created a second. It slows down though and by the time five thousand objects are created it's almost 2 seconds for 100 objects and by the time ten thousand objects are created, it's 4 seconds per 100 objects. The whole group of 21000 objects takes more than 10 minutes. That is with all the actual useful code taken out (that's just a fetch and an object create). And it's much much slower on the actual device (by maybe 4 times as much).

What I don't understand is why core data starts off fast but then begins to slow down. I've tried both with index and no indexes on my data. I've tried creating my own autorelease pool which I periodically drain in my loop. I've tried saving after every object creation. I've tried waiting until the end to save. But no matter what I do, the performance still seems miserable. Is it just that slow to add a new object to a core data store with a few thousand objects in it? Any suggestions?

+1  A: 

Try using Instruments. Don't you save after inserting every single object? Actually, more insert-related code and scheme may be very useful.

beefon
A: 

From the Core Data Programming Guide

Importing in batches

First, you should typically create a separate managed object context for the import, and set its undo manager to nil. (Contexts are not particularly expensive to create, so if you cache your persistent store coordinator you can use different contexts for different working sets or distinct operations.)

Setting the undo manager to nil means that:

  1. You don’t waste effort recording undo actions for changes (such as insertions) that will not be undone;
  2. The undo manager doesn’t maintain strong references to changed objects and so prevent them from being deallocated (see “Change and Undo Management”).
falconcreek
Thanks, but the undo manager is set to nil by default on the iPhone.
Mike
+1  A: 

It can be quite speedy but it depends on what you are doing. As others have suggested you should be looking at Instruments and finding the actual hotspot. Also posting the actual import code would help to identify the issue.

Marcus S. Zarra