【问题标题】:Core Data - get/create NSManagedObject performance核心数据 - 获取/创建 NSManagedObject 性能
【发布时间】:2010-09-29 14:22:29
【问题描述】:

我正在创建一个 iphone/ipad 应用程序,它基本上读取 XML 文档并从基于 xml 创建的对象创建表视图。 xml 代表文件系统中的“级别”。它基本上是一个浏览器。

每次我解析 xml 文档时,我都会更新在核心数据 sqllite 数据库中镜像的文件系统。对于 xml 中遇到的每个“文件”,我都会尝试获取与之关联的 NSManagedObject。

问题是我用来获取/创建一个新的空白实体或从数据库中获取现有实体的这个函数。

+(File*)getOrCreateFile:(NSString*)remotePath 
        context:(NSManagedObjectContext*)context
 {
        struct timeval start,end,res;
        gettimeofday(&start,NULL);
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"File" inManagedObjectContext:context];
        [fetchRequest setEntity:entity];
        [fetchRequest setFetchLimit:1];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"remotePath == %@",remotePath];
        [fetchRequest setPredicate:predicate];

        NSError *error;
        NSArray *items = [context executeFetchRequest:fetchRequest error:&error];
        [fetchRequest release];

        File *f;
        if ([items count] == 0) 
            f = (File*)[NSEntityDescription insertNewObjectForEntityForName:@"File" inManagedObjectContext:context];
        else 
            f = (File*)[items objectAtIndex:0];

        gettimeofday(&end, NULL);
        [JFS timeval_subtract:&res x:&end y:&start];
        count++;
        elapsed += res.tv_usec;
        return f;

}

对于 eksample,如果我正在解析包含 200 个文件的文档,则在 iPhone 3G 上的总时间约为 4 秒。其中 3 秒用于此函数从核心数据中获取对象。

RemotePath 是可变长度的唯一字符串,并在 sqllite 数据库中建立索引。

我在这里做错了什么?或者..我可以做些什么更好/不同来提高性能。

【问题讨论】:

    标签: performance core-data


    【解决方案1】:

    在 Core Data 中执行 fetch 的成本有点高,尽管 Core Data 工程师做了一些了不起的工作来将这种影响降到最低。因此,您可以通过运行 fetch 一次返回多个项目来稍微改进一下。例如,批处理 remotePaths 并使用谓词获取,例如

    [NSPredicate predicateWithFormat:@"remotePath IN %@", paths];
    

    paths 是可能路径的集合。

    根据结果,您可以在内存中进行搜索以确定是否存在特定路径。

    然而,从根本上说,对字符串进行提取(即使已编入索引)是一项昂贵的操作。你可以做的可能不多。考虑获取非字符串属性,也许通过拥有路径并将散列保存在实体中。您将返回一个(可能)更大的结果集,然后您可以在内存中搜索字符串是否相等。

    最后,不要在没有一些性能数据的情况下进行任何更改。个人资料,个人资料,个人资料。

    【讨论】:

    • 在数据模型中,每个文件夹与每个子文件夹(文件夹/文件)具有一对多的关系。我最终使用了 [NSFetchRequest setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObject:@"children"] 并且这将每个孩子作为错误返回,然后每次我都使用 NSPredicate 搜索内存中的孩子集合而不是调用另一个函数。原帖的 4 秒现在是 1.5ish。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2011-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多