データをフェッチし、計算を実行してから結果を返すために処理に時間がかかるメソッドがいくつかあります。たとえば、このインスタンス メソッドは 3 つのパラメーターに基づいて配列を返します。
-(NSArray*)periodsForCompanies:(NSArray*)companies figureType:(NSString*)figureType
actualValuesOnly:(BOOL)actualValuesOnly
{.. };
このメソッドは、同じクラスから同じパラメーターを使用して何度も呼び出される可能性があり、完了するまでに時間がかかるため、このメソッドのコードが毎回完全に実行されるのを避けるために、コードを最適化したいと考えています。
以前のパラメーター (および/または結果) をメソッド内に保存して、現在のパラメーターを以前のパラメーターと比較し、コードを再度実行する必要があるかどうかを判断するにはどうすればよいですか? この場合の「ベストプラクティス」とは何ですか?
私の理解では、通常、メソッド内のすべての変数は、メソッドが呼び出されるとゼロと nil にリセットされます。
編集
リクエストにより、コードサンプルを追加しました:
- (NSArray*)periodsForCompanies:(NSArray*)companies figureType:(NSString*)figureType actualValuesOnly:(BOOL)actualValuesOnly
{
// fetch all periods
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"IBEstPeriod"];
NSPredicate *predicate = [[NSPredicate alloc]init];
if (actualValuesOnly == YES)
predicate = [NSPredicate predicateWithFormat:@"(company IN %@) AND (ANY estType.actValue != nil) AND (ANY estType.type == %@)", self.companies, figureType];
else
predicate = [NSPredicate predicateWithFormat:@"(company IN %@) AND (ANY estType.type == %@)", self.companies, figureType];
request.predicate = predicate;
request.resultType = NSDictionaryResultType;
request.returnsDistinctResults = YES;
request.propertiesToFetch = @[@"endCalYear",@"endMonth",@"periodLength"];
request.sortDescriptors =
@[[NSSortDescriptor sortDescriptorWithKey:@"endCalYear" ascending:NO],
[NSSortDescriptor sortDescriptorWithKey:@"endMonth" ascending:NO],
[NSSortDescriptor sortDescriptorWithKey:@"periodLength" ascending:NO]];
NSError *fetchError = nil;
NSArray *results = [self.managedObjectContext executeFetchRequest:request error:&fetchError];
NSMutableArray *distinctPeriods = results.mutableCopy;
if (fetchError) {
NSLog(@"Error during fetch request:%@", [fetchError localizedDescription]);
} else {
// NSLog(@"results: %@",results);
}
// remove periods for which not all companies have data for estimate type specified
NSString const *endCalYearKey = @"endCalYear";
NSString const *endMonthKey = @"endMonth";
NSString const *periodLengthKey = @"periodLength";
const NSIndexPath *yoyGrowthIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
const NSIndexPath *seqGrowthIndexPath = [NSIndexPath indexPathForRow:1 inSection:0];
const NSIndexPath *customGrowthIndexPath = [NSIndexPath indexPathForRow:2 inSection:0];
NSMutableIndexSet *indexesForPeriodsToRemove = [NSMutableIndexSet indexSet];
[distinctPeriods enumerateObjectsUsingBlock:^(NSDictionary *estPeriodDict, NSUInteger idx, BOOL *stop) {
NSNumber *endCalYear = estPeriodDict[endCalYearKey];
NSNumber *endMonth = estPeriodDict[endMonthKey];
NSNumber *periodLength = estPeriodDict[periodLengthKey];
NSPredicate *predicate = [[NSPredicate alloc]init];
UITableView *tableView = [self tableView];
if ( [[tableView indexPathForSelectedRow] isEqual:customGrowthIndexPath] ) {
// company predicate:
predicate = [NSPredicate predicateWithFormat: @"ANY estimateType.type == %@ "
"AND SUBQUERY(estimatePeriod, $x, $x.endCalYear == %@ AND $x.endMonth == %@ AND $x.periodLength == %@ AND ANY $x.estType.type == %@).@count > 0",
figureType,
endCalYear, endMonth, periodLength, figureType];
} else if ( [[tableView indexPathForSelectedRow] isEqual:yoyGrowthIndexPath] ) {
predicate = [NSPredicate predicateWithFormat: @"ANY estimateType.type == %@ "
"AND SUBQUERY(estimatePeriod, $x, $x.endCalYear == %@ AND $x.endMonth == %@ AND $x.periodLength == %@ AND ANY $x.estType.type == %@).@count > 0"
"AND SUBQUERY(estimatePeriod, $x, $x.endCalYear == %i AND $x.endMonth == %@ AND $x.periodLength == %@ AND ANY $x.estType.type == %@).@count > 0",
figureType,
endCalYear, endMonth, periodLength, figureType,
endCalYear.integerValue - 1, endMonth, periodLength, figureType];
} else if ( [[tableView indexPathForSelectedRow] isEqual:seqGrowthIndexPath] ) {
// TODO: rewrite
predicate = [NSPredicate predicateWithFormat: @"ANY estimateType.type == %@ "
"AND SUBQUERY(estimatePeriod, $x, $x.endCalYear == %@ AND $x.endMonth == %@ AND $x.periodLength == %@ AND ANY $x.estType.type == %@).@count > 0",
figureType,
endCalYear, endMonth, periodLength, figureType];
} else {
[NSException raise:NSInternalInconsistencyException format:@"TableView: Invalid selection state in section 0 (NSIndexPath: %@)",super.tableView.indexPathForSelectedRow];
}
NSArray *companiesWithDataForPeriod = [self.companies filteredArrayUsingPredicate:predicate];
NSLog(@"type: %@, period: %@/%@(%@), companies: %@", figureType, endCalYear, endMonth, periodLength,[companiesWithDataForPeriod valueForKey:@"contrSymbol"]);
// mark periods which are not defined for all companies for removal (from display):
if ( companiesWithDataForPeriod.count < self.companies.count ) [indexesForPeriodsToRemove addIndex:idx];
}]; // end block
[distinctPeriods removeObjectsAtIndexes:indexesForPeriodsToRemove];
return distinctPeriods;
}