我希望提高我的 Mac OS X 应用程序(日志文件解析器)的性能,并且不介意寻求一些关于并行化导入过程的技术指导。我的应用程序的基本要点是它获取一个日志文件(可能长达数十万行),它读取、解析并存储到 Core Data 数据库中以供后续过滤/分析。
我正在使用多个父/子托管对象上下文来确保导入发生在主线程之外,如下所示:
NSPrivateQueueConcurrencyType (root MOC)
^^
NSMainQueueConcurrencyType (UI MOC)
^^
NSConfinementConcurrencyType (import MOC)
从数据库的角度来看,这工作得很好,我现在正在寻求提高每行可以被标记/解析的速度。我在 Instruments 上花了很多很多时间,并且相信标记/解析单个日志行的路径已经得到了很好的优化。但是,遍历每一行是(当前)一个顺序过程......我想做的是在一个线程上读取这些行,然后将每一行交给工作线程池进行处理(经典的生产者/消费者情况)。
我能想到的几种模式是:
- 创建一个
NSConfinementConcurrencyType
MOC 池,然后当我遍历这些行时,在[moc performBlock:]
. 看起来相当简单,但是让每个块[moc save:]
每隔几千条记录调用一次并且知道所有块何时最终完成可能会很有趣(我有一些摘要级别的信息需要在导入所有行后进行整理)。 - 为每一行创建一个
NSOperationQueue
并输入一个NSOperation
。NSOperation
为每一行创建一个似乎有点笨拙(记住每个日志文件中可能有数十万行)。还需要一种方法来确保每个操作都有一个有效的 MOC(同样,为每一行创建一个新的子 MOC 似乎有点矫枉过正) - 使用 GCD。使用类似的东西在 GCD 块中启动操作
dispatch_group_async
给了我一个很好的方式来了解事情何时完成,但是,我仍然需要一种分配 MOC 并确保 GCD 块在正确的 MOC 线程上执行的方法。可能[moc performBlockAndWait:]
在内部使用,dispatch_group_async
但我对混合同步和异步调用的死锁有点警惕。
对各种方法的陷阱/好处有任何想法吗?我错过了什么方法?正如我之前所说,这似乎是一个相当经典的生产者/消费者问题(我可能倾向于将 GCD 作为解决方案),但是,MOC 管理的额外皱纹让我停下来思考。
有人走过这条路,有什么想分享的想法吗?
非常感谢。克雷格