Core Data に MusicInterest という名前のエンティティがあります。これらを一度に 5000 ほど追加する必要があり、現在のプロセスでは、MusicInterest が既に存在するかどうかを照会し、存在しない場合は新しいものを作成します。
これには、各タイトルが存在するかどうかを確認するためにストアに 5000 回アクセスする必要があるようです。もちろん、挿入トリップもありますが、5000 クエリが私の速度を低下させています。
各 FacebookFriend には複数の音楽への関心があり、文字列タイトルの配列を使用してそれぞれを列挙し、次のコードを呼び出します。
これを最適化する方法はありますか?
+ (MusicInterest*) musicInterestForFacebookFriend:(FacebookFriend*)facebookFriend WithTitle:(NSString*)musicTitle UsingManagedObjectContext:(NSManagedObjectContext*)moc
{
// query to see if there
NSArray *matches = [self queryForMusicTitle:musicTitle moc:moc];
if (([matches count] >= 1)) {
// NSLog(@"Music already in database");
MusicInterest *existingMusic = [matches lastObject];
[existingMusic addLikedByObject:facebookFriend];
return [matches lastObject];
} else {
// create new Music Interest
MusicInterest *newMusic = [NSEntityDescription insertNewObjectForEntityForName:@"MusicInterest" inManagedObjectContext:moc];
newMusic.title = musicTitle;
[newMusic addLikedByObject:facebookFriend];
return newMusic;
}
}
+ (NSArray *)queryForMusicTitle:(NSString *)MusicTitle moc:(NSManagedObjectContext *)moc
{
// query to see if there
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"MusicInterest"];
request.predicate = [NSPredicate predicateWithFormat:@"title == %@", [NSString stringWithFormat:@"%@", MusicTitle]];
NSError *error = nil;
NSArray *matches = [moc executeFetchRequest:request error:&error];
if (error) {
NSLog(@"Error querying title in Music interest. Error = %@", error);
}
return matches;
}
アップデート:
Core Data プログラミング ガイドで提案されている設計を採用したところ、時間が 12 秒から 4 秒に短縮されました (まだ他の領域での最適化が必要です :)
このガイドにはサンプル コードの半分しか含まれていません。完全な実装を共有したいと思います。
musicArray = [[music componentsSeparatedByString:@", "] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
if (obj1 > obj2)
return NSOrderedDescending;
else if (obj1 < obj2)
return NSOrderedAscending;
return NSOrderedSame;
}];
if (musicArray) {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"MusicInterest"];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"title IN %@", musicArray]];
[fetchRequest setSortDescriptors:
@[[[NSSortDescriptor alloc] initWithKey: @"title" ascending:YES]]];
NSError *fetchError = nil;
NSArray *musicInterestMatchingTitles = [backgroundContext executeFetchRequest:fetchRequest error:&fetchError];
if ([musicArray count] > 0) {
// walk musicArray and musicInterestsMatchingTitles in parallel
for (int i = 0; i < [musicArray count]; i++) {
NSString *title = musicArray[i];
if (i < [musicInterestMatchingTitles count]) {
MusicInterest *comparingMusicInterest = musicInterestMatchingTitles[i];
// compare each title
if (![title isEqualToString:comparingMusicInterest.title]) {
// if it doesn't exist as a ManagedObject (a MusicInterest), create one
MusicInterest *musicInterest = [MusicInterest createNewMusicInterestUsingManagedObjectContext:backgroundContext];
musicInterest.title = title;
[musicInterest addLikedByObject:friend];
} else {
// otherwise, just establish the relationship
[comparingMusicInterest addLikedByObject:friend];
}
} else {
// if there are no existing matching managedObjects, create one
MusicInterest *musicInterest = [MusicInterest createNewMusicInterestUsingManagedObjectContext:backgroundContext];
musicInterest.title = title;
[musicInterest addLikedByObject:friend];
}
}
}
}
}];
[self saveBackgroundContext:backgroundContext];