Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to improve large data import performance with core data in ios

I'm importing ~18,000 records of various entities that are related to each other from a web service on first launch of an iOS app. The records have their own unique identifiers from the database on the web. I have read and re-read apple's documentation, cimgf's blog entries, Marcus Zarra's books on core data, and watched over and over again the iDeveloper TV's series on core data. I can't figure out a way to import Entity A without keeping Entity B, C, and D in memory or performing expensive fetches and maintain relationships between the entities. If I were not using core data, I'd be able to just use the unique identifiers that are already established and the import would be much faster.

If you have any suggestions, I'm all ears.

We've implemented this strategy in Android and the import takes ~2.5 minutes compared to ~6 minutes on iOS where the hardware on the different devices are comparable. Shortening the import time is crucial to our users so I have not been able to compromise on this issue. Thanks in advance for your help.

EDIT:

Here's how I'm currently doing it - I create an NSOperation which creates it's own context. I import Entities B, C, & D first and keep an array per entity type. I then import Entity A and use predicates to filter the arrays for Entities B, C, & D in order to relate Entity A to the appropriate Entities in B, C, & D. I'm batch saving the context at optimized intervals that are different depending on which entity type I'm currently importing.

I'm not just importing to one table, I'm importing many tables that are related to each other. So If I import Entity B, I have to either keep Entity B in memory or fetch it when I need it to relate Entity B to Entity A. Make sense?

like image 821
Ross Chapman Avatar asked Jan 10 '12 14:01

Ross Chapman


People also ask

Is Core Data fast?

Core Data was designed with speed and efficiency in mind. It only fetches the data your application needs and fills in the gaps as your application asks for more data.

What is the use of Core Data in iOS?

Overview. Use Core Data to save your application's permanent data for offline use, to cache temporary data, and to add undo functionality to your app on a single device. To sync data across multiple devices in a single iCloud account, Core Data automatically mirrors your schema to a CloudKit container.

Should I use Core Data?

The next time you need to store data, you should have a better idea of your options. Core Data is unnecessary for random pieces of unrelated data, but it's a perfect fit for a large, relational data set. The defaults system is ideal for small, random pieces of unrelated data, such as settings or the user's preferences.


1 Answers

I will raise the same issue every Core Data question gets, and then move on: Make sure that you really want to use Core Data for this and not just sqlite directly. Core Data is for persisting object graphs, not a general database. If you've already implemented a database for Android, then you may want to use the same schema and design on iOS.

OK, got that out of the way. Let's assume CD is really the best tool for the job here (or you can't change it at this point). My first thought here is to cheat. Granted, that is often one of my early thoughts....

See how fast you can insert these objects with no relationships. If that's fast enough, then here's how you cheat: don't store actual relationships at first. Store a string list of identifiers that describe the relationship. Then, once everything's loaded and the user can start working, over time convert the string relationships into real relationships in the background. Whenever you fetch a record, you need to check if it has a cheater-property still set and if so, you'll need to fetch its relationships by hand (and then clear the cheater-property).

This doesn't make the full import faster, but it gives the illusion that it's faster, and that's the goal in iOS 90% of the time. You might even have to prevent certain operations (like delete) until you've finished gluing everything, but that's probably still better than blocking the user entirely.

like image 129
Rob Napier Avatar answered Nov 16 '22 16:11

Rob Napier