gpt4 book ai didi

iphone - 使用 SQLite 后端修复谓词 NSFetchedResultsController/NSFetchRequest 性能?

转载 作者:行者123 更新时间:2023-12-03 19:42:56 26 4
gpt4 key购买 nike

我有一系列 NSFetchedResultsControllers 为一些 TableView 提供支持,它们在设备上的性能非常糟糕,大约需要几秒。由于它全部在主线程上运行,因此它在启动时阻塞我的应用程序,这不太好。

我调查并发现谓词是问题所在:

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 毫秒。)

(我之前在这里嵌套了另一个问题,现在我 moved away )。

最佳答案

对于我们许多尝试在 iPhone 上使用 Core Data 来处理更大的数据库或更复杂的模式的人来说,这是一个持续存在的问题。我的个人资料包含与此相关的几个不同 SO 问题的链接 - 在全文搜索的上下文中。

并非所有应用程序仅通过将谓词应用于一对多关系就会变得很慢,因此还有更多内容。请参阅Apple's performance document 。设置-com.apple.CoreData.SQLDebug 1。

检查是否有索引(如果适用)。确保没有调用任何阻止 sqlite 有效连接或使用索引的 sql 函数(例如格式/类型转换)。

如果实体中有很多行并且有很多属性,则可能会出现内存问题。考虑将一个实体拆分为一个较小的实体,其中包含一些用于搜索的属性,并在需要时提取其余的属性。

如果您的谓词比一对多关系部分更复杂,那么您可以尝试分两步进行搜索。例如。 SQL 可能会低效地先连接然后过滤,而不是先过滤然后连接。但这样做会破坏 NSFetchedResultsController。尽管如此,它可能会揭示一些问题。

我不会做类似将 ObjectID 打包到属性中来创建您自己的多外键引用之类的事情。听起来像是一个可怕的黑客行为,肯定会阻止您认真使用 Core Data...但 Core Data 的优势有很多。

尝试删除或添加反向关系。我发现在一种情况下,如果没有反向关系,我的查询运行得更快。缺点是删除反向关系会使我的数据库变得臃肿。

让我们知道您发现了什么。

关于iphone - 使用 SQLite 后端修复谓词 NSFetchedResultsController/NSFetchRequest 性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2197496/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com