使用NSPredicates过滤~WEIRD获取核心数据所需的时间

时间:2012-02-07 23:18:51

标签: iphone objective-c xcode cocoa-touch core-data

所以,我试图从核心数据中获取大约2000个对象,并试图找出最快的方法来获取它们。

没有NSPredicates:

当我添加此块(下面)时,if语句占用了执行总时间的90%,这是可以理解的,因此我将其注释掉。

Block {

    NSError *error;
    NSManagedObjectContext *context =  <#Get the context#>;

    // The IF block

/*   if (![context save:&error])
    {
        NSLog(@"error %@", error);
    }
*/
       // The block above takes 90% of the total time of fetch

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *theEntity = [NSEntityDescription 
                                  entityForName:@"EntityName" inManagedObjectContext:context];

    [fetchRequest setEntity:theEntity];

    NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];    

    }

使用NSPredicates:

我将谓词设置为

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"handle == %@",handle];

并执行与Block()

中显示的相同的抓取工作

可以看出,如果我使用IF BLOCK ~6秒,整体时间恰好相反 - 大约快90%。

否则,如果对该块进行了注释,则提取时间大约为3分钟。仅当为predicate设置fetchRequest时才会发生这种情况。

有人可以解释一下吗?

即,

 /*
 Save + straight fetch = slow, due to saving. 
 Straight fetch - pretty fast. 
 Predicate fetch, slow. 
 Save + predicate fetch, much faster? 
 */

3 个答案:

答案 0 :(得分:2)

(猜想,希望受过教育)保存后,上下文可以直接对数据库执行谓词提取,因为它知道没有任何对象的更改尚未写入数据库。如果没有保存,它必须针对数据库以及可能有未保存更改的任何现存对象进行提取。

答案 1 :(得分:1)

当我试图理解Core Data的内部工作原理时,使用以下参数打开SQL Debug会有所帮助:

    -com.apple.CoreData.SQLDebug 1

这将打印出正在执行的所有SQL语句,因此您可以真正看到差异。在保存之后,持久存储(或者可能只是索引)仍然在缓存中,使得索引(谓词)获取更快,这也是可能的(仅仅是理论)。

无论如何,SQL Debug将向您显示执行的语句以及何时 - 可能会导致模型中的某些优化以进行索引。

答案 2 :(得分:0)

效率提升与您执行提取的方式无关。

您延迟的原因是您在if块中保存。这是一项非常昂贵的操作。如果你做了2000次,可能需要几秒钟甚至更长时间。

当您从持久性存储中获取实体时,只有在您修改这些实体时才进行保存是没有意义的。即便如此,您仍会尝试将通话保存到最低限度。