2013-10-03 4 views
0

이 문제는 많이 제기되었지만이 검색 코드를 더 이상 최적화 할 수 없습니다.nspredicates를 사용하여 검색을위한 쿼리 최적화

이 filterSet 배열은 약 1000 항목을 가지고 있으며 (적은 초보다 시뮬레이터에 결과를 보여줍니다) 비 시뮬레이터 아이 패드에 결과를 재현하는 팔초을 복용 :

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 문자열과 일치하는 조건자를 만드는 더 빠르고 효율적인 방법이 있습니까? 나는 makeArject 메서드를 사용하여 NSArray 메서드를 사용하는 것에 대해 생각해 보았습니다. 그러나 어떤 이유로 NSCFNumber 인식 할 수없는 선택기 문제가 발생했습니다 (내 배열에는 NSString 대신 NSNumbers가 있습니다)

답변

0

그래서 내 초기 알고리즘은 O (N^2) 그것은 현실적으로 얻을만큼 나쁘다.

I 쉽게 루프의 첫 번째 패스에 대한 제 내에 그들을 참조 할 수 있도록 I 키/값을 매핑 할있는 NSDictionary를 사용 끝내했습니다

NSMutableDictionary * filteredResultsDict = [[[NSMutableDictionary의 ALLOC] INIT] 오토 릴리즈를] ; 루프 내 실제에

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

    } 
} 

후, 나는 이전 rowResults 대신이를 호출 할 수

NSNumber *rowIDNum = [NSNumber numberWithInteger: [rowID integerValue]]; 
    rowResults = [[filteredResultsDict objectForKey:rowIDNum] valueForKey:@"value"]; 
+0

수정 된 접근 방식과 같은 성능이 무엇입니까? – jbbenni

+1

에 931 개의 항목이 있으면 초기 알고리즘이 실행되고 8.2971 초 내에 완료됩니다. 이 최적화를 사용하면 1.97 초로 줄어 듭니다. :) – kevinl