ios - 核心数据插入和保存缓慢

标签 ios swift parsing core-data optimization

我正在从一个包含大约 20000 个对象的 JSON 文件中解析数据。我一直在运行时间分析器来找出我的瓶颈在哪里并加快解析速度,我已经设法将解析时间减少了 45%,但是根据时间分析器,我有 78% 的时间被context.save() 以及整个解析过程中的大部分重要部分都来 self 称为 NSEntityDescription.insertNewObjectForEntityForName 的地方。

有没有人知道是否有任何方法可以加快速度?我目前每 5000 个对象对我的保存进行一次批处理。我尝试了 100、1000、2000、5000、10000 的分组,我发现 5000 在我运行的设备上是最佳的。我已经阅读了 Core Data Programming Guide但发现它给出的大部分建议是优化大量数据的获取,而不是解析或插入。

答案很可能是,Core Data 有其局限性,但我想知道是否有人找到了进一步优化插入数千个对象的方法。

更新

根据要求提供一些关于我如何处理解析的示例代码

class func parseCategories(data: NSDictionary, context: NSManagedObjectContext, completion: ((success: Bool) -> Void)) {

    let totalCategories = data.allValues.count
    var categoriesParsed = 0

    for (index, category) in data.allValues.enumerate() {
        let privateContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
        privateContext.persistentStoreCoordinator = (UIApplication.sharedApplication().delegate as! AppDelegate).persistentStoreCoordinator!
        privateContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy

        //Do the parsing for this iteration on a separate background thread
        privateContext.performBlock({ () -> Void in

            guard let categoryData = category.valueForKey("category") as? NSArray else{
                print("Fatal Error: could not parse the category data into an NSArray. This should never happen")
                completion(success: false)
                return
            }

            let newCategory: Categories?
            do {
                let newCategory = NSEntityDescription.insertNewObjectForEntityForName("Categories", inManagedObjectContext: privateContext) as! Categories
                newCategory.name = category.valueForKey("name") as? String ?? ""
                newCategory.sortOrder = category.valueForKey("sortOrder") as? NSNumber ?? -1

                SubCategory.parseSubcategories(category.valueForKey("subcategories") as! NSArray, parentCategory: newCategory, context: privateContext)
            } catch {
                print("Could not create the Category object as expected \(error)")
                completion(success: false)
            }

            do {
                print("Num Objects Inserted: \(privateContext.insertedObjects.count)") //Num is between 3-5k
                try privateContext.save()
            } catch {
                completion(success: false)
                return
            }

            categoriesParsed+=1
            if categoriesParsed == totalCategories{
                completion(success: true)
            }
        })
    }
}

在上面的代码中,我查看了我称之为“类别”的顶级数据对象,我为每个对象分离了后台线程以同时进行解析。这个顶级对象只有 3 个,因此线程不会太重。

每个类别都有子类别,以及其他几个级别的子对象,每个子对象都会产生数千个插入的对象。

我的核心数据堆栈配置了一个 sqlite 数据库,这是使用 CoreData 创建应用程序时配置的标准方式

最佳答案

一个原因是您要在每次迭代中保存托管对象上下文,这既昂贵又不需要。插入最后一项后保存。

关于ios - 核心数据插入和保存缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35490799/

相关文章:

php - 当 haystack 包含额外标记时,文本解析器会在 needle 上给出假阴性

ios - Swift MKMapView 在 GameScene 中返回 nil

ios - JWT 使用 HMACSHA256 验证签名并通过 Swift 显示 "Invalid Signature"

ios - css 背景大小 : contain ignored on IOS?

swift - 带有 Swift 协议(protocol)的通用类

ios - 添加 UIBarButtonItem 覆盖 UINavigationController 后退按钮

c# - 字符串到日期时间 "hh:mm:ss"或 "dd.mm.yyyy hh:mm:ss"格式

ruby - 使用转义字符解析定界文本

ios - NSDate 比较显示错误的值?

ios 在 View 执行期间禁用/启用旋转