いくつかのテーブルビューを強化する一連の NSFetchedResultsControllers があり、デバイスでのパフォーマンスは数秒程度でひどいものでした。すべてがメイン スレッドで実行されるため、起動時にアプリがブロックされます。これは良くありません。
私が調査したところ、述語が問題であることがわかりました。
NSPredicate *somePredicate = [NSPredicate predicateWithFormat:@"ANY somethings == %@", something];
[fetchRequest setPredicate:somePredicate];
つまり、フェッチエンティティは、それを「もの」と呼び、エンティティ「何か」と多対多の関係を持っています。この述語は、特定の「何か」と関係があるものだけに結果を制限するフィルターです。
テストのために述語を削除すると、フェッチ時間 (最初の performFetch: 呼び出し) が (極端なケースでは) 4 秒から約 100 ミリ秒以下に減少しました。これは許容範囲です。ただし、Core Data と NSFRC を使用して得ることを望んでいた多くの利点が無効になるため、これには悩まされています。
それで、私の質問は、どうすればこのパフォーマンスを最適化できるでしょうか? 述語を間違って使用していますか? モデル/スキーマを何らかの方法で変更する必要がありますか? そして、これを修正する他の方法は何ですか?この種のパフォーマンスの低下は予想されますか? (1KB 未満のオブジェクトが数百個あります。)
詳細を編集:
コードは次のとおりです。
[fetchRequest setFetchLimit:200];
NSLog(@"before fetch");
BOOL success = [frc performFetch:&error];
if (!success) {
NSLog(@"Fetch request error: %@", error);
}
NSLog(@"after fetch");
更新されたログ (以前は、ここでパフォーマンスを低下させるいくつかのアプリケーションの非効率性がありました。これらは、現在の環境で取得できる限り最適に近い更新されたログです):
2010-02-05 12:45:22.138 Special Ppl[429:207] before fetch
2010-02-05 12:45:22.144 Special Ppl[429:207] CoreData: sql: SELECT DISTINCT 0, t0.Z_PK, t0.Z_OPT, <model fields> FROM ZTHING t0 LEFT OUTER JOIN Z_1THINGS t1 ON t0.Z_PK = t1.Z_2THINGS WHERE t1.Z_1SOMETHINGS = ? ORDER BY t0.ZID DESC LIMIT 200
2010-02-05 12:45:22.663 Special Ppl[429:207] CoreData: annotation: sql connection fetch time: 0.5094s
2010-02-05 12:45:22.668 Special Ppl[429:207] CoreData: annotation: total fetch execution time: 0.5240s for 198 rows.
2010-02-05 12:45:22.706 Special Ppl[429:207] after fetch
述語なしで同じフェッチを行う場合 (質問の冒頭にある 2 行をコメントアウトすることにより):
2010-02-05 12:44:10.398 Special Ppl[414:207] before fetch
2010-02-05 12:44:10.405 Special Ppl[414:207] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, <model fields> FROM ZTHING t0 ORDER BY t0.ZID DESC LIMIT 200
2010-02-05 12:44:10.426 Special Ppl[414:207] CoreData: annotation: sql connection fetch time: 0.0125s
2010-02-05 12:44:10.431 Special Ppl[414:207] CoreData: annotation: total fetch execution time: 0.0262s for 200 rows.
2010-02-05 12:44:10.457 Special Ppl[414:207] after fetch
20倍のタイム差。500ミリ秒はそれほど大きくはありません.バックグラウンドスレッドでそれを行う方法や、私が考えることができる最適化する方法はないようです. (これが問題にならないバイナリ ストアに行くことは別として、私はそうするかもしれません。バイナリ ストアのパフォーマンスは、200 を超えるオブジェクトの述語クエリで一貫して ~100 ミリ秒です。)
(以前にここに別の質問をネストしましたが、現在は移動しました)。