0

This issue has been brought up a lot but I can't seem to optimize this piece of search code any further.

this filterSet array has about 1000 items and it's taking 8 seconds to reproduce results on a non-simulator iPad (simulator shows results in less than a second):

for(NSString *rowID in [self.filterSet array]) {

    self.rowResults = [self.filteredResults filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"rowID = %@", rowID]];
    self.rowResults = [self.rowResults valueForKey:@"value"];
    self.duplicateValueSet = [NSOrderedSet orderedSetWithArray:self.rowResults];
    filterCount = [[self.resultsArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF = %@", rowID]] count];

    if([self.duplicateValueSet count] != filterCount) 
        filterCount -= abs([self.duplicateValueSet count] - filterCount);

    if(filterCount == matchingCount)
        [self.results addObject:rowID];
}

any suggestions to optimizing this query? The majority of the search is taken up in all the filters and predicate sorting. thanks.

edit: so i removed a lot of the code in the for loop and found the culprit to be the first line

self.rowResults = [self.filteredResults filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"rowID = %@", rowID]];

this is for some reason taking 7 seconds to execute. Is there a faster/more efficient way to create a predicate to match the rowID string? I've thought about using the makeobjectsperformselector NSArray method but for some reason I get the NSCFNumber unrecognized selector issue (which is saying my array has NSNumbers instead of NSStrings)

4

1 回答 1

0

所以我的初始算法在 O(N^2) 上运行,这几乎和它得到的一样糟糕(实际上)。

我最终使用 NSDictionary 来映射键/值,以便我可以在第一个 for 循环的第一遍中轻松引用它们:

NSMutableDictionary *filteredResultsDict = [[[NSMutableDictionary alloc] init] autorelease];

for (int i = 0; i < [filteredResults count]; i++) {
    NSString *key = [[filteredResults objectAtIndex:i] valueForKey:@"rowID"];
    NSMutableArray *filtersArray = [NSMutableArray array];
    NSMutableArray *tempArray = [filteredResultsDict objectForKey:key];

    if (tempArray != nil || [tempArray count] > 0) {
        [tempArray addObject:[filteredResults objectAtIndex:i]];
        [filteredResultsDict setValue:tempArray forKey:key];
    }
    else {
        [filtersArray addObject:[filteredResults objectAtIndex:i]];
        [filteredResultsDict setValue:filtersArray forKey:key];

    }
}

然后在我实际的 for 循环中,我可以调用它来代替前面的 rowResults:

    NSNumber  *rowIDNum = [NSNumber numberWithInteger: [rowID integerValue]];
    rowResults = [[filteredResultsDict objectForKey:rowIDNum] valueForKey:@"value"];
于 2013-10-03T22:52:15.910 回答