gpt4 book ai didi

iphone - 我如何优化这个基于核心数据的搜索?

转载 作者:可可西里 更新时间:2023-11-01 04:36:34 24 4
gpt4 key购买 nike

我正在尝试在我的应用中实现搜索。有两个核心数据实体,“Tag”和“DvarTorah”。一个标签只有一个字符串。 “DvarTorah”具有标题、文本内容和一些其他属性。我正在尝试找出快速搜索它们的最佳方法。该应用程序附带了大约 1200 个 DvarTorah 实体,甚至更多的标签。现在,当我的搜索 View Controller 调用 viewDidLoad 时,我加载了一个 NSFetchedResultsController。然后,当用户在搜索框中输入内容或更改范围时,我调用一个方法,该方法同时接收范围栏值和搜索词,并过滤我的对象数组。这是它的样子:

- (void) filterArrayWithSearchTerm:(NSString *)searchString andScopeIndex:(NSInteger)scopeIndex{

if ([searchString isEqualToString:@""]) {
return;
}

NSMutableArray *unfilteredResults = [[[[self.fetchedResultsController sections] objectAtIndex:0] objects] mutableCopy];

if (self.filteredArray == nil){
self.filteredArray = [[[NSMutableArray alloc ] init] autorelease];
}

[filteredArray removeAllObjects];

NSPredicate *predicate = [[[NSPredicate alloc] init] autorelease];

if (scopeIndex == 0) {
predicate = [NSPredicate predicateWithFormat:@"dvarTorahTitle CONTAINS[cd] %@", searchString];
}else if (scopeIndex == 1) {
predicate = [NSPredicate predicateWithFormat:@"searchableContent CONTAINS[cd] %@", [searchString canonicalString]];
}else if (scopeIndex == 2){
predicate = [NSPredicate predicateWithFormat:@"ANY tags.tagText CONTAINS[cd] %@", searchString];
}else{
predicate = [NSPredicate predicateWithFormat:@"(ANY tags.tagText CONTAINS[cd] %@) OR (dvarTorahTitle CONTAINS[cd] %@) OR (searchableContent CONTAINS[cd] %@)", searchString,searchString,searchString];
}

for (DvarTorah *dvarTorah in unfilteredResults) {
if ([predicate evaluateWithObject:dvarTorah]) {
[self.filteredArray addObject:dvarTorah];
}
}

[unfilteredResults release];
}

问题是我的搜索方法非常慢。我知道 CONTAINS 可能是罪魁祸首,但即使在存储了内容的规范版本(如 searchableContent)并尝试进一步优化之后,搜索速度也非常慢。我怎样才能让它更快?

编辑:

根据 Jacob 的初步建议,这是我的新方法:

    if ([searchString isEqualToString:@""]) {
return;
}

if (self.filteredArray == nil) {
self.filteredArray = [[[NSMutableArray alloc ] init] autorelease];
}

[filteredArray removeAllObjects];

NSPredicate *predicate = nil;

if (scopeIndex == 0) {
predicate = [NSPredicate predicateWithFormat:@"dvarTorahTitle CONTAINS[cd] %@", searchString];
}else if (scopeIndex == 1) {
predicate = [NSPredicate predicateWithFormat:@"searchableContent CONTAINS[cd] %@", [searchString canonicalString]];
}else if (scopeIndex == 2){
predicate = [NSPredicate predicateWithFormat:@"ANY tags.tagText CONTAINS[cd] %@", searchString];
}else{
predicate = [NSPredicate predicateWithFormat:@"(ANY tags.tagText CONTAINS[cd] %@) OR (dvarTorahTitle CONTAINS[cd] %@) OR (searchableContent CONTAINS[cd] %@)", searchString,searchString,searchString];
}

[self.filteredArray addObjectsFromArray:[[[[[self.fetchedResultsController sections] objectAtIndex:0] objects] mutableCopy] filteredArrayUsingPredicate:predicate]];

}

编辑2:

不再复制数组,仍然很慢:

- (void) filterArrayWithSearchTerm:(NSString *)searchString andScopeIndex:(NSInteger)scopeIndex{

if ([searchString isEqualToString:@""]) {
return;
}

if (self.filteredArray == nil) {
self.filteredArray = [[[NSMutableArray alloc ] init] autorelease];
}

[filteredArray removeAllObjects];

NSPredicate *predicate = nil;

if (scopeIndex == 0) {
predicate = [NSPredicate predicateWithFormat:@"dvarTorahTitle CONTAINS[cd] %@", searchString];
}else if (scopeIndex == 1) {
predicate = [NSPredicate predicateWithFormat:@"searchableContent CONTAINS[cd] %@", [searchString canonicalString]];
}else if (scopeIndex == 2){
predicate = [NSPredicate predicateWithFormat:@"ANY tags.tagText CONTAINS[cd] %@", searchString];
}else{
predicate = [NSPredicate predicateWithFormat:@"(ANY tags.tagText CONTAINS[cd] %@) OR (dvarTorahTitle CONTAINS[cd] %@) OR (searchableContent CONTAINS[cd] %@)", searchString,searchString,searchString];
}

[self.filteredArray addObjectsFromArray:[[[[self.fetchedResultsController sections] objectAtIndex:0] objects] filteredArrayUsingPredicate:predicate]];
}

最佳答案

这里有很多东西在消耗 CPU 周期和内存:

第一,您正在制作从 NSFetchedResultsController 获取的结果的可变副本。为什么?

第二,您在上面的结果上使用 for..in 结构,并在每个结果上调用 -[NSPredicate evaluateWithObject:]。您可以修改谓词搜索字符串以使用 -[NSArray filteredArrayUsingPredicate:] 代替,这很可能比您的方法更快。

第三,您的 predicate 变量存在一个相当微妙的问题 - 您总是将它重新分配给除开始时自动释放的空值之外的其他内容。为其指定默认值 nil

第四,正如您提到的,您的谓词字符串效率很低。我认为您需要做一些叫做索引 或类似的事情。

有关使用 Core Data 进行全文搜索的更多信息:

http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/CoreData/Articles/cdPerformance.html

http://cocoawithlove.com/2008/03/testing-core-data-with-very-big.html

http://cocoawithlove.com/2009/11/performance-tests-replacing-core-data.html

http://www.mlsite.net/blog/?page_id=1194

Is SQLite FTS3 still the best way to go for rolling out your full text search?

sqlite Indexing Performance Advice

Full Text Searching in Apple's Core Data Framework

关于iphone - 我如何优化这个基于核心数据的搜索?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8464773/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com