0

この問題は何度も取り上げられていますが、この検索コードをこれ以上最適化することはできないようです。

この filterSet 配列には約 1000 個の項目があり、シミュレーター以外の iPad で結果を再現するのに 8 秒かかります (シミュレーターは 1 秒未満で結果を表示します)。

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];
}

このクエリを最適化するための提案はありますか? 検索の大部分は、すべてのフィルターと述語の並べ替えで取り上げられます。ありがとう。

編集: for ループ内の多くのコードを削除し、原因が最初の行であることがわかりました

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

これは何らかの理由で実行に 7 秒かかります。rowID 文字列に一致する述語を作成するためのより高速で効率的な方法はありますか? makeobjectsperformselector NSArray メソッドを使用することを考えましたが、何らかの理由で NSCFNumber 認識されないセレクターの問題が発生します (これは、配列に NSStrings ではなく NSNumbers があることを示しています)。

4

1 に答える 1

0

そのため、私の最初のアルゴリズムは O(N^2) で実行されていましたが、これは (現実的に) かなり悪いです。

最初の for ループの最初のパス内で簡単に参照できるように、NSDictionary を使用してキー/値をマップすることになりました。

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 に答える