【问题标题】:Time taken for Core-data fetch with NSPredicates filtering ~ WEIRD使用 NSPredicates 过滤获取核心数据所花费的时间 ~ WEIRD
【发布时间】:2012-02-29 10:20:35
【问题描述】:

所以,我试图从核心数据中获取大约 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 分钟。仅当为fetchRequest 设置predicate 时才会发生这种情况。

谁能解释一下?

也就是说,

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

【问题讨论】:

  • 显示更多代码。什么是“IF块”?你如何使用那个块?以及如何创建 NSFetchRequest?
  • @MatthiasBauch 请检查编辑。 !
  • 所以让我直截了当,因为我发现这个问题写得有点令人困惑。保存 + 直接提取 = 慢,由于保存。直接获取 - 相当快。谓词获取,慢。保存 + 谓词提取,快得多?
  • @jrturton 是的!没错!

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


【解决方案1】:

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

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

当您从持久存储中获取实体时,保存是没有意义的,除非您要修改这些实体。即便如此,您也会尽量减少通话费用。

【讨论】:

  • 是的,我明白了。这就是为什么我在没有NSPredicates 的情况下在我的代码中使用它,它需要大约 0.02 秒。但是,当我使用 NSPredicates 过滤我的 fetch 和 IF BLOCK is present 时,一次 fetch 需要 0.02 秒......而without the IF BLOCK 一次 fetch 需要 0.25 秒。所以,当我有 2000 次获取时,你可以想象它所花费的时间!!!很奇怪吧?
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

        -com.apple.CoreData.SQLDebug 1
    

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

    无论如何,SQL 调试都会向您显示执行了哪些语句以及何时执行 - 可能会导致您的模型对索引进行一些优化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-10
      • 1970-01-01
      • 2014-03-29
      • 2023-04-04
      • 1970-01-01
      • 2016-10-08
      相关资源
      最近更新 更多