Why is this piece of code so slow? (CoreData & NSSet)

时间:2022-09-25 18:00:32

I have an app and I'm implementing full text search. I have 2 enitites: Keywords and Articles with a many-to-many relationship between them. The problematic piece of code is this:

我有一个应用程序,我正在实施全文搜索。我有2个enitites:关键字和文章,它们之间有多对多的关系。有问题的代码是这样的:

            keywordsInRange = [[[CoreDataManager sharedManager] managedObjectContext]  executeFetchRequest:request error:&err];



            for(Keywords* word in keywordsInRange) {
                NSDate *methodStart = [NSDate date];

                [mySet addObjectsFromArray:[word.article allObjects]];

                NSDate *methodFinish = [NSDate date];
                NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart];
                NSLog(@"Keyword Search Exec Time: %.3f", executionTime);
            }

the output is this:

输出是这样的:

Keyword Search Exec Time: 0.235  //added 1 article
Keyword Search Exec Time: 0.216  //added 6 articles
Keyword Search Exec Time: 0.211  //etc
Keyword Search Exec Time: 0.205
Keyword Search Exec Time: 0.204

as you can see, to add all articles linked to a keyword in the set takes unexpectedly long time when I test on the device (iPad iOS 4.2.1). When I test in the simulator the times are:

正如您所看到的,当我在设备上进行测试时(iPad iOS 4.2.1),在集合中添加链接到关键字的所有文章会花费很长时间。当我在模拟器中测试时,时间是:

0.029
0.026
0.026
0.026
0.026

Where is the mistake, what can I do to speed things up?

错误在哪里,我该怎么做才能加快速度?

2 个解决方案

#1


0  

I'm not an expert of CoreData but isn't it lazily loading articles ? If yes, it means there a query executing against the store for every keyword.

我不是CoreData的专家,但不是懒得加载文章吗?如果是,则表示针对每个关键字针对商店执行查询。

#2


0  

Try calling [request setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObject:@"article"]]; before the first line of your code above.

尝试调用[request setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObject:@“article”]];在上面代码的第一行之前。

Otherwise, the each iteration in the loop generates a new fetch for the articles although you really only need one.

否则,循环中的每次迭代都会为文章生成新的提取,尽管您确实只需要一个。

It is often helpful in this case to use SQLDebug to see the actual SQL statements being generated. To do so, right-click on your executable, click on Get Info, go to the Arguments tab and add -com.apple.CoreData.SQLDebug 1 in "Arguments to be passed on launch".

在这种情况下,使用SQLDebug查看生成的实际SQL语句通常很有帮助。要执行此操作,请右键单击您的可执行文件,单击“获取信息”,转到“参数”选项卡,然后在“要在启动时传递的参数”中添加-com.apple.CoreData.SQLDebug 1。

#1


0  

I'm not an expert of CoreData but isn't it lazily loading articles ? If yes, it means there a query executing against the store for every keyword.

我不是CoreData的专家,但不是懒得加载文章吗?如果是,则表示针对每个关键字针对商店执行查询。

#2


0  

Try calling [request setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObject:@"article"]]; before the first line of your code above.

尝试调用[request setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObject:@“article”]];在上面代码的第一行之前。

Otherwise, the each iteration in the loop generates a new fetch for the articles although you really only need one.

否则,循环中的每次迭代都会为文章生成新的提取,尽管您确实只需要一个。

It is often helpful in this case to use SQLDebug to see the actual SQL statements being generated. To do so, right-click on your executable, click on Get Info, go to the Arguments tab and add -com.apple.CoreData.SQLDebug 1 in "Arguments to be passed on launch".

在这种情况下,使用SQLDebug查看生成的实际SQL语句通常很有帮助。要执行此操作,请右键单击您的可执行文件,单击“获取信息”,转到“参数”选项卡,然后在“要在启动时传递的参数”中添加-com.apple.CoreData.SQLDebug 1。