提高更新Core Data中现有记录(~11000)的速度

时间:2012-05-01 17:57:28

标签: ios core-data nsfetchrequest

我正在解析大量数据,我最初将其插入到核心数据存储中。

稍后,我正在解析相同的XML,尽管其中一些可能已经更新。然后我做的是检查具有相同标签的现有记录,如果已存在,我用数据更新记录。

然而,虽然我的初始解析(大约11.000条记录)需要8秒左右,但更新似乎很昂贵,需要144秒(这些是模拟器运行,因此在实际设备上显着更长)。

虽然第一次很好(我正在显示进度条),但第二次是不可接受的长,我想做一些事情来提高速度(即使它发生在一个单独的线程的后台)。

不幸的是,这不是find-or-create的问题,因为XML中的数据可能已经针对单个记录进行了更改,因此每个记录都需要更新。

我对属性进行了索引,这加快了初始解析和更新,但它仍然很慢(上面的数字都带有索引)。我注意到解析/更新似乎逐渐减慢。虽然最初很快,但随着越来越多的记录被处理,它会越来越慢。

所以最后我的问题是,如果对我如何提高我更新数据集的速度有什么建议?我正在使用MagicalRecord获取记录。这是代码:

Record *record;
if (!isUpdate) {
    record = [NSEntityDescription insertNewObjectForEntityForName:@"Record" inManagedObjectContext:backgroundContext];
} else {
    NSPredicate *recordPredicate = [NSPredicate predicateWithFormat:@"SELF.tag == %@", [[node attributeForName:@"tag"] stringValue]];
    record = [Record findFirstWithPredicate:recordPredicate];
}

4 个答案:

答案 0 :(得分:3)

不是进行大量的提取,而是对每个实体类型执行一次查询,并按标记将它们存储在字典中,然后只检查字典是否存在具有该键的对象。您应该能够将propertiesToFetch设置为仅包含标记,并且应该减少开销。

答案 1 :(得分:1)

您可以尝试的一件事是使用模板NSPredicate,这样您就不会为每个正在执行的查找/获取重新解析格式字符串。

所以在你进入你的循环之前:

NSPredicate *template = [NSPredicate predicateWithFormat:@"SELF.tag == $RECORD_TAG"];

循环内部:

Record *record;
if (!isUpdate) {
    record = [NSEntityDescription insertNewObjectForEntityForName:@"Record" inManagedObjectContext:backgroundContext];
} else {
    NSPredicate *recordPredicate = [];
    record = [Record findFirstWithPredicate:[template predicateWithSubstitutionVariables:[NSDictionary dictionaryWithObject:[[node attributeForName:@"tag"] stringValue] forKey:@"RECORD_TAG"]];
}

有关详细信息,请参阅Apple的Predicate Programming Guide

答案 2 :(得分:1)

您还可以尝试将Senior的答案与属性的散列相结合。

在插入哈希属性并将该哈希存储为Record的一种校验和属性 在更新时,您将获取的属性设置为标记和校验和,并对所有项进行一次提取。然后,当您对数据集进行迭代时,如果校验和与已获取的校验和不同,则可以获取Record并更新它。

答案 3 :(得分:1)

所有性能问题的初始答案是运行仪器。然后,使用该数据,您可以识别问题区域。从那里开始,您可能会对提高绩效的某些方面有其他具体问题。

我们人类在识别性能瓶颈方面非常糟糕。所以,首先使用仪器。它肯定会告诉你你的时间花在哪里。