1

私はバックグラウンドキューの子モックでデータ処理を行っています。更新中の既存のオブジェクトと作成中の新しいオブジェクトを区別できるように、データベースをIDでクエリする必要があります。ほとんどの場合(合計処理時間は50アイテムで約2秒)がによって消費されていることがわかりましたexecuteFetchRequest:error:。これNSPredicateは最も単純な形式です—単一のID属性に一致するだけで(ID属性はすでにインデックス付けされています)、NSFetchRequest1つまたはnoneを返す必要があります(IDは一意です)。この種を最適化する方法はありますNSFetchRequestか?

これが私の現在のコードです:

+ (User *)userWithID:(NSNumber *)ID inManagedObjectContext:(NSManagedObjectContext *)context {
    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"User"];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ID == %@", ID];
    [fetchRequest setPredicate:predicate];
    [fetchRequest setFetchBatchSize:1];

    NSError *error = nil;
    NSArray *users = [context executeFetchRequest:fetchRequest error:&error];
    if (error) {
        abort();
    }

    if ([users count] == 1) {
        return [users objectAtIndex:0];
    } else if ([users count] > 1) {
        // Sanity check.
        …
    } else {
        return nil;
    }
}
4

2 に答える 2

1

@ChrisH が質問の下のコメントで指摘したように、すべての ID に対してフェッチを行うのは良くありません。そこで、処理フローを次のように変更しました。

  1. 最初にデータを列挙して ID を抽出します。
  2. 単一のフェッチを実行して、ID に一致するすべての既存のユーザーをフェッチし、それらを ID ( という名前existingUsers) をキーとする辞書に入れます。
  3. 2 回目にデータを列挙して実際の処理を行います。反復ごとに、 で見つかった既存のユーザーを 1 人更新するかexistingUsers、新しいユーザーを作成して に追加しますexistingUsers

コードはほぼ 2 倍になりますが、パフォーマンスも同様です。本当に良いトレードオフです!

于 2012-10-03T02:17:30.787 に答える
1

私のコメントを元の質問に拡張するには、データをインポートするときに Core Data でフェッチ要求を繰り返し実行するのは効率的ではありません。

@an0 が示したように、最も簡単な方法は、チェックする既存のすべてのオブジェクトを 1 回フェッチしてから、チェックする属性を持つオブジェクトをキーとして含む NSDictionary を作成することです。したがって、元の User と userID の例に固執します。

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"User"];

NSError *error = nil;

NSArray *users = [context executeFetchRequest:fetchRequest error:&error];

if (error) {
  //handle appropriately
}

NSMutableDictionary *userToIdMap = [NSMutableDictionary dictionary];

for (User *user in users){

  [userToIdMap setObject:user forKey:user.ID];

}

これで、新しいデータを処理するメソッドでuserToIdMap、フェッチ リクエストを行う代わりに辞書を確認できます。

大規模なデータ セットに適した、より洗練されたアプローチは、Core Data Programming Guide のEfficently Importing Dataで概説されています。「効率的な検索または作成の実装」というセクションを見てください。ここで Apple が提案したアプローチでは、作成した配列をどのように処理するかに関するコードが欠落しています。その問題に対する私の解決策は、この SO の質問にあります:基本的な配列比較アルゴリズム

于 2012-10-03T16:53:07.203 に答える