我有一系列 NSFetchedResultsController 为一些表视图提供动力,它们在设备上的性能非常糟糕,大约为几秒。由于它全部在主线程上运行,它在启动时阻塞了我的应用程序,这不是很好。
我调查并发现谓词是问题所在:
NSPredicate *somePredicate = [NSPredicate predicateWithFormat:@"ANY somethings == %@", something];
[fetchRequest setPredicate:somePredicate];
即获取实体,称为“事物”,与实体“事物”具有多对多关系。该谓词是一个过滤器,它将结果限制为仅与特定“某物”有关系的事物。
当我删除谓词进行测试时,获取时间(初始 performFetch: 调用)从 4 秒(对于某些极端情况)下降到大约 100 毫秒或更短,这是可以接受的。不过,我对此感到困扰,因为它否定了我希望通过 Core Data 和 NSFRC 获得的很多好处,否则这似乎是一个强大的工具。
所以,我的问题是,如何优化这种性能?我使用谓词错误吗?我应该以某种方式修改模型/模式吗?还有什么其他方法可以解决这个问题?这种性能下降是可以预料的吗?(大约有数百个 <1KB 的对象。)
编辑细节:
这是代码:
[fetchRequest setFetchLimit:200];
NSLog(@"before fetch");
BOOL success = [frc performFetch:&error];
if (!success) {
NSLog(@"Fetch request error: %@", error);
}
NSLog(@"after fetch");
更新的日志(以前,我有一些应用程序效率低下,降低了性能。这些更新的日志应该尽可能接近最佳状态,因为你可以在我当前的环境下获得):
2010-02-05 12:45:22.138 Special Ppl[429:207] before fetch
2010-02-05 12:45:22.144 Special Ppl[429:207] CoreData: sql: SELECT DISTINCT 0, t0.Z_PK, t0.Z_OPT, <model fields> FROM ZTHING t0 LEFT OUTER JOIN Z_1THINGS t1 ON t0.Z_PK = t1.Z_2THINGS WHERE t1.Z_1SOMETHINGS = ? ORDER BY t0.ZID DESC LIMIT 200
2010-02-05 12:45:22.663 Special Ppl[429:207] CoreData: annotation: sql connection fetch time: 0.5094s
2010-02-05 12:45:22.668 Special Ppl[429:207] CoreData: annotation: total fetch execution time: 0.5240s for 198 rows.
2010-02-05 12:45:22.706 Special Ppl[429:207] after fetch
如果我在没有谓词的情况下进行相同的提取(通过注释掉问题开头的两行):
2010-02-05 12:44:10.398 Special Ppl[414:207] before fetch
2010-02-05 12:44:10.405 Special Ppl[414:207] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, <model fields> FROM ZTHING t0 ORDER BY t0.ZID DESC LIMIT 200
2010-02-05 12:44:10.426 Special Ppl[414:207] CoreData: annotation: sql connection fetch time: 0.0125s
2010-02-05 12:44:10.431 Special Ppl[414:207] CoreData: annotation: total fetch execution time: 0.0262s for 200 rows.
2010-02-05 12:44:10.457 Special Ppl[414:207] after fetch
时间相差20倍。500ms 并不是那么好,而且似乎没有办法在后台线程中完成它或以其他方式优化我能想到的。(除了去二进制存储这成为一个非问题,所以我可能会这样做。对于上述 200 个对象的谓词查询,二进制存储性能始终为 ~100 毫秒。)
(我之前在这里嵌套了另一个问题,现在我搬走了)。