4

Apple のドキュメント (リンク) によると—</p>

個別の入力値のセットに対して、既存のオブジェクト (ストアに既に保存されているオブジェクト) を検索する必要がある状況は数多くあります。簡単な解決策は、ループを作成し、次に各値に対してフェッチを実行して、一致する永続化されたオブジェクトがあるかどうかを判断することです。このパターンはうまくスケーリングしません。このパターンでアプリケーションをプロファイリングすると、通常、(項目のコレクションを反復するだけの場合と比べて) フェッチがループ内でよりコストのかかる操作の 1 つになることがわかります。さらに悪いことに、このパターンはO(n)問題を問題に変えO(n^2)ます。

可能であれば、1 回のパスですべての管理対象オブジェクトを作成し、2 回目のパスで関係を修正する方がはるかに効率的です。たとえば、重複が含まれていないことがわかっているデータをインポートする場合 (たとえば、最初のデータ セットが空であるため)、データを表す管理対象オブジェクトを作成するだけで、検索はまったく実行できません。または、関係のない「フラット」データをインポートする場合は、セット全体の管理対象オブジェクトを作成し、単一の大きなIN 述語を使用して、保存する前に重複を取り除く (削除する) ことができます。

質問 1:インポートしているデータに関係がないことを考慮して、最後の行に記載されている内容をどのように実装すればよいですか?

検索または作成のパターンに従う必要がある場合 (たとえば、関係情報が属性情報と混在している異種データをインポートしている場合など)、フェッチの回数を最小限に抑えることで、既存のオブジェクトの検索方法を最適化できます。実行する。これを達成する方法は、操作する必要がある参照データの量によって異なります。100 個の潜在的な新しいオブジェクトをインポートしていて、データベースに 2000 個しかない場合、既存のものをすべてフェッチしてそれらをキャッシュしても、大きなペナルティにはならない可能性があります (特に操作を複数回実行する必要がある場合)。ただし、データベースに 100,000 個のアイテムがある場合、それらをキャッシュに保持するためのメモリ プレッシャーが非常に大きくなる可能性があります。

IN 述語と並べ替えを組み合わせて使用​​すると、Core Data の使用を 1 つのフェッチ要求に減らすことができます。

コード例:

// Get the names to parse in sorted order.
NSArray *employeeIDs = [[listOfIDsAsString componentsSeparatedByString:@"\n"]
        sortedArrayUsingSelector: @selector(compare:)];

// create the fetch request to get all Employees matching the IDs
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:
        [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:aMOC]];
[fetchRequest setPredicate: [NSPredicate predicateWithFormat: @"(employeeID IN %@)", employeeIDs]];

// Make sure the results are sorted as well.
[fetchRequest setSortDescriptors:
    @[ [[NSSortDescriptor alloc] initWithKey: @"employeeID" ascending:YES] ]];
// Execute the fetch.
NSError *error;
NSArray *employeesMatchingNames = [aMOC executeFetchRequest:fetchRequest error:&error];

最終的に 2 つの並べ替えられた配列が作成されます。1 つはフェッチ要求に渡された従業員 ID を含み、もう 1 つはそれらに一致する管理対象オブジェクトを含みます。それらを処理するには、次の手順に従って並べ替えられたリストをたどります。

次の ID と Employee を取得します。ID が従業員 ID と一致しない場合は、その ID の新しい従業員を作成します。次の従業員を取得: ID が一致する場合は、次の ID と従業員に移動します。

質問 2:上記の例では、上記のように 2 つの並べ替えられた配列を取得します。挿入されるすべてのオブジェクトがストアに存在するという最悪のシナリオを考えると、問題をO(n)時間内に解決できるとは思えません。Apple は 2 つのステップを上記のように説明していますが、それはO(n^2)仕事です。入力配列の任意のkth要素について、出力配列の最初の要素に一致する要素が存在する場合と存在しない場合がありkます。したがって、最悪の場合、複雑さは になりますO(nC2) = O(n^2)

したがって、Apple が行っていると私が信じているのは、O(n^2)チェックが必要な場合でも、プロセスを 1 回だけフェッチするようにすることです。もしそうなら、私はこれで行きます。しかし、これを効率的に行う他の方法はありますか。

何度も何度もフェッチしたくないことを理解してください。サイズ 100 の識別子の入力配列に対して 1 回フェッチします。

4

2 に答える 2