简单的核心数据提取非常慢

Nor*_*ert 7 iphone performance core-data

我的iPhone应用程序有一个Words具有属性的实体word,lengthlanguage.两者都被编入索引: 实体和属性

我将cdatamodel和数据库复制到一个单独的导入器应用程序,在该应用程序中预先填充了大约400,000个不同语言的单词.我通过查看SQLite文件验证了导入,然后将预填充的数据库复制回iPhone项目.

首先,我认为(简单)谓词是问题所在.但即使从获取请求中删除谓词,也需要很长时间才能执行:

2011-09-01 09:26:38.945 MyApp[3474:3c07] Start
2011-09-01 09:26:58.120 MyApp[3474:3c07] End
Run Code Online (Sandbox Code Playgroud)

这是我的代码的样子:

// Get word
NSLog(@"Start");
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Words" inManagedObjectContext:appDelegate.managedObjectContext];
[fetchRequest setEntity:entity];

NSError *error = nil;
NSArray *fetchedObjects = [appDelegate.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
    //... error handling code
}

[fetchRequest release];
NSLog(@"End");
return fetchedObjects;
Run Code Online (Sandbox Code Playgroud)

数据库中的条目数是Core Data的问题吗?


编辑:正如gcbrueckmann和jrturton指出的那样,这是一个很好的设置点fetchBatchSize.但是获取时间仍然不尽如人意:

  • 谓词集2秒:

    NSPredicate*predicate = [NSPredicate predicateWithFormat:@"length ==%d AND language BEGINSWITH%@",wordLength,lng]; [fetchRequest setPredicate:predicate];

  • 批量大小设置为7秒:

    [fetchRequest setFetchBatchSize:1];

  • 1秒,同时设置谓词和批量大小

还有另一个瓶颈吗?

gcb*_*ann 12

由于您不以任何方式限制结果集,一次取出400,000个对象肯定会成为Core Data的负担.有几种方法可以提高性能:

更改提取请求fetchBatchSize限制了提取将一次保留在内存中的对象数.此功能对您的应用程序完全透明,因此绝对值得一试.

如果您不需要完全成熟的对象,可以考虑将获取请求更改resultType为更合适的值.特别是如果你只对某个对象的某些值感兴趣,那么使用它NSDictionaryResultType是一个好主意.

最后,如果要自己管理批处理,则fetchLimitfetchOffset属性允许您限制结果范围.如果您对每个结果对象的处理使用大量内存,这是一个好主意,因为您可以将每个批处理包装在一起NSAutoreleasePool(只是不要试图为每个结果对象创建一个自动释放池).

我想1秒.可能只是在你的情况下快速 - 即使你求助于一个普通的Sqlite数据库.我能想到的唯一进一步优化是每种语言使用一个表(而不是将所有语言中的单词放入单个表中).当然,这只适用于Sqlite,除非您为所有语言定义单独的实体,即将您的Words实体保持原样并使其成为抽象.然后添加EnglishWord子实体等.来自不同实体的对象存储在单独的表中.因此,结合使用fetchBatchSizepredicate参数,它应该与Sqlite方法类似地执行,并为所有语言使用单独的表.