I have a Core Data application with:
- 549 Account entities with myJournals relationship (one to many)
- 24000 Ledger entities with myJournals relationship (one to many)
- 57000 Journal entities with myAccount and myLedger (one to one) inverse relationship
Each entity has a uuidKey string attribute with a UUID string imported from an online database.
I'm trying to run the app on an iPhone 5S. Inserting objects is relatively fast, but finding and linking the relationships is longer than anticipated.
let debugTime = NSDate()
let thisRequest = NSFetchRequest(entityName: "Ledgers")
let keyLeft = NSExpression(forKeyPath: "uuidKey")
let keyRight = NSExpression(forConstantValue: ledgerKey)
let keyPredicate = NSComparisonPredicate(leftExpression: keyLeft, rightExpression: keyRight, modifier: NSComparisonPredicateModifier.DirectPredicateModifier, type: NSPredicateOperatorType.EqualToPredicateOperatorType, options: NSComparisonPredicateOptions.allZeros)
thisRequest.predicate = keyPredicate
thisRequest.fetchBatchSize = 1
thisRequest.fetchLimit = 1
println("DEBUG COMMENT: \(debugTime.timeIntervalSinceNow) time to create thisRequest.")
var keyError: NSError? = nil
if let keyArray = self.managedObjectContext!.executeFetchRequest(thisRequest, error: &keyError) {
if keyArray.isEmpty {
myLedger = nil
} else {
if let thisLedger = keyArray[0] as? Ledgers {
println("DEBUG COMMENT: \(debugTime.timeIntervalSinceNow) time to find thisLedger.")
myLedger = thisLedger
} else {
myLedger = nil
}
}
}
println("DEBUG COMMENT: \(debugTime.timeIntervalSinceNow) time to link myLedger.")
I get log times like this:
DEBUG COMMENT: -9.20295715332031e-05 time to create thisRequest.
DEBUG COMMENT: -0.174275994300842 time to find thisLedger.
DEBUG COMMENT: -0.174659013748169 time to link myLedger.
DEBUG COMMENT: -0.00464397668838501 time to find and link myAccount.
0.092 milliseconds to create the NSFetchRequest is fine. 174 milliseconds to find the Ledger? On an indexed UUID string when there are 24k Ledgers?!? When I need to link this to 57k Journals?
Faster is always better. 4 milliseconds to find a link myAccount when there are 549 accounts is slightly disappointing but acceptable. For the Ledger search I was expecting about 25-50 milliseconds, not 174!
I'm running this in its own core data store and context:
// Initialize the persistent store coordinator for the sync session.
let url = appDel.applicationDocumentsDirectory.URLByAppendingPathComponent("FoodyCoreModel.sqlite")
self.syncStore = NSPersistentStoreCoordinator(managedObjectModel: appDel.managedObjectModel)
var error: NSError? = nil
var failureReason = "There was an error creating or loading the application's saved data."
let storeOptions: [NSObject: AnyObject] = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true]
self.syncStore.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: storeOptions, error: &error)
// Initialize the managed object contextfor the sync session
self.syncContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
self.syncContext.persistentStoreCoordinator = self.syncStore
let nmp = NSMergePolicy(mergeType: NSMergePolicyType.MergeByPropertyStoreTrumpMergePolicyType)
self.syncContext.mergePolicy = nmp
Is this reasonable performance to expect with an iPhone 5S? I've read many of the Core Data performance questions here, but many of them date from years ago. I was hoping that iOS 8 and more recent devices would be significantly faster. I'm not trying to do a MATCHES or CONTAINS search, just EQUALS on an indexed text field!
I've read the Core Data Performance Guide. Is there something I'm missing or am I just expecting too much from a mobile device?