[英]predicateWithFormat is very slow
我在coredata NSManagedObjectContextDidSaveNotification中运行谓词,以过滤我感兴趣的相关对象。
- (void)didSaveNotficiation:(NSNotification*)notification
{
NSSet *objects = nil;
NSMutableSet *combinedSet = nil;
NSPredicate *predicate = nil;
NSDictionary *userInfo = [notification userInfo];
objects = [userInfo objectForKey:NSInsertedObjectsKey];
combinedSet = [NSMutableSet setWithSet:objects];
objects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
[combinedSet unionSet:objects];
objects = [[notification userInfo] objectForKey:NSDeletedObjectsKey];
[combinedSet unionSet:objects];
//THis is slow
predicate = [NSPredicate predicateWithFormat:@"entity.name == %@ && %K == %@",
[XXContact entityName], XXContactRelationship.user,self];
[combinedSet filterUsingPredicate:predicate];
if ([combinedSet count] == 0) {
return;
}
[self process];
/* This is much faster
[combinedSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
if ([obj isKindOfClass:[XXContact class]]) {
XXContact* contact = (XXContact*)obj;
if (contact.user == self) {
[self process];
*stop = YES;
}
}
}];
*/
}
应用启动时,该通知可以被调用100多次。 当我分析应用程序时,函数predicateWithFormat似乎很慢,占用了20%的cpu。 甚至过滤速度也不慢。 谓词本身的创建是如此缓慢。 如果将其更改为使用enumerateObjectsUsingBlock,它将变得更快,但代码的可读性较差。
有人有解释吗? 谢谢。
由于以下几个原因,您无法击败使用当前谓词进行枚举过滤所获得的时间:
didSaveNotficiation :
调用中分配,解析和组成谓词didSaveNotficiation :
combinedSet
所有对象) 我相信您最好的选择是自己实施谓词
为了改善您的谓词实现,我建议:
//1. change .name property to an Integer/Enum value
//2. make your predicate static and reduce the compose and parse needs:
//(If you must use %K in your predicate this would be much harder)
//NOT TESTED
static NSPredicate* p = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
p = [NSPredicate predicateWithFormat:@"entity.name == $ENAME AND user == $USEROBJECT"];
});
NSPredicate* currPredicate = [p predicateWithSubstitutionVariables:@{@"ENAME" : [XXContact entityName], @"USEROBJECT" : [self objectID]}];
[combinedSet filterUsingPredicate:currPredicate];
如您所见,如果您尝试提高可读性会受到影响。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.