NSManagedObjectContext保存的性能急剧下降

| 基于CoreData的iOS应用程序尝试从服务器发送的数据构建初始数据库时遇到问题。基本上,服务器发送1MB的对象块(每个块约3,000个),iOS客户端对它们进行反序列化并将其写入磁盘。 我看到的是,对于前8个块(总共44个),一切进展顺利,然后性能急剧下降,每个块开始花费的时间越来越长,如下图所示。如在Instruments分析数据中所看到的,几乎所有时间都用在ѭ0中,但是由于某种原因,看来该应用程序不再以100%的CPU运行,例如它在磁盘I / O上等待或者其他的东西。 有关如何执行此操作的一些重要事实: 每个块都在自己的ѭ1中和自己的
NSAutoreleasePool
中进行处理,因此在处理块之间的非刷新上下文中不会建立对象。 在任何上下文中都没有设置“ 3”。 没有ѭ4出现(即,块上下文未将其更改推送到“主”上下文中) 我在iOS 4.3上使用基于SQLite的数据存储。 正在写入的记录确实具有索引。 整个同步作业在单个GCD后台线程(即
dispatch_queue_create()
dispatch_async()
)上处理。 我不知道为什么性能会突然下降,或者该如何解决。我已经翻阅并阅读了以下内容,但还没有任何东西出现在我身上: http://cocoawithlove.com/2008/03/testing-core-data-with-very-big.html 保存ManagedObjectContext的性能是否取决于所包含(不变)对象的数量? 任何使该应用程序可在数据库中扩展至100,000条记录的想法或指针,将不胜感激。 编辑-额外统计 该“仪器”图显示了与上述相同的模拟(在iPad2上),但包括磁盘活动状态,您可以很清楚地看到所有“不以100%CPU运行”时间似乎都花在了写入磁盘上。 我也在iOS模拟器上运行了相同的同步尝试。每个字典的整体内存使用情况或多或少是恒定的,除了包含对象ID随时间而增长的字典(但这些不是CoreData对象或任何会影响保存的对象,它们只是NSNumbers)。与总堆相比,此dict占用的内存较少,因此该问题不会耗尽内存。 此测试的有趣之处在于,CoreData Save仪器报告连续的保存大约花费相同的时间,这显然与第一组结果中的CPU分析信息冲突。似乎CoreData认为将更改推送到数据库需要花费相同的时间,但是数据库本身(即SQLite)突然需要更长的时间才能将这些更改实际流式传输到磁盘。     
已邀请:
我知道这是一个老问题,因此这可能与您不再相关,但可能与其他人有关。 我已经看到在iCloud上播种Core Data数据库时出现的性能问题,并且发现如果数据模型上存在逆向关系,那么在性能方面会受到极大的伤害。实际上,iCloud事务日志的实现方式似乎是不可避免的问题。发送到iCloud的每笔交易(请在developer.icloud.com上进行查看-它们只是压缩文件)记录了受更改影响的每个关系。与在核心数据中修改关系的一端并处理相反的一端不同,核心数据事务日志在两端记录更改,而不是在两端进行记录。 因此,如果您具有一对多的关系,并且您创建了另一个记录,该记录最终将挂在“很多”端,那么“ 1”端的记录也将被更新以反映新的事实。额外的记录现在悬而未决。如果您的体系结构意味着您有一个挂起许多\'data \'对象的\'type \'对象,则每次添加新的数据对象时,类型都会为其编写一个事务以及-这是关键,因为iCloud核心数据交易记录的是已编辑实体的整个状态,而不仅是更改,已针对它记录的每个关系也都添加到了日志中,而不仅仅是表示新实体的关系下属记录。随着实体之间关系数量的增加,随着写入的数据量的增加,这很快就会失控。最终,保存批处理的时间越来越长。 在Apple开发者论坛上,我之前已经回答过类似的问题,这可能很有用,因为我似乎永远无法简洁地描述这一点。 如果这种情况正在影响您,那么提高播种性能的最简单选择就是关闭逆向关系,但这并不总是一种选择。     
        有关您的实施的更多信息将有所帮助。例如,您是在主线程上运行还是在实现后台线程?但是,我以前已经看到过这种行为。当使用Core Data执行大量批处理操作时,如果内存管理不当,它可能会减慢速度。您检查内存使用情况了吗?您检查泄漏了吗?要尝试的另一件事是,如果需要,请确保您正确使用了NSAutoreleasePool。通过定期排空池,可能有助于提高性能。     

要回复问题请先登录注册