我有一个核心数据应用程序:
每个实体都有一个uuidKey字符串属性,其中包含从在线数据库导入的UUID字符串。
我正在尝试在iPhone 5S上运行该应用程序。插入对象的速度相对较快,但查找和链接关系的时间比预期的要长。
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.")
我得到这样的日志时间:
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.
创建NSFetchRequest的0.092毫秒很好。 174毫秒找到Ledger?在有24k Ledgers的索引UUID字符串上?!?当我需要将其链接到57k期刊时?
更快更好。 4,5毫秒查找链接myAccount当有549个帐户时略微令人失望但可以接受。对于Ledger搜索,我期待大约25-50毫秒,而不是174!
我在自己的核心数据存储和上下文中运行它:
// 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
iPhone 5S的性能是否合理?我在这里阅读了很多核心数据性能问题,但其中很多都是几年前的。我希望iOS 8和更新的设备速度要快得多。我不打算在索引文本字段上进行匹配或包含搜索,只是EQUALS!
我已阅读Core Data Performance Guide。有什么我想念的东西,或者我只是期望从移动设备上得到太多东西?
答案 0 :(得分:4)
您的代码中最可能的减速是您一次获取一个Ledger
个实例,并且您说其中有24,000个实例。无论如何,这将是一个主要的瓶颈。无论您是否在谓词中使用字符串ID,获取都是一项相对昂贵的操作,因此您的代码将花费大部分时间来获取。
您应该分批提取而不是一次提取。将50或100左右的uuidKey
值收集到一个数组中,并使用类似"uuidKey in %@"
的谓词格式,并将数组作为替换变量。处理批处理,并重复完成。
有关如何有效导入数据的更多详细信息,请参阅Apple的"Efficiently Importing Data"指南,尤其是“有效实现查找或创建”一节。
顺便说一句,使用这样的println
是衡量效果的一种非常糟糕的方法。使用仪器。它会以更少的开销为您提供更多细节,并且不会使代码混乱,并且可以帮助您确定瓶颈的确切位置。