1

I have copied all the local contacts and stored them in core data,now when i use time profiler instrument,it shows me a large amount of time is being spent on deleting local contacts from my app.Can anyone suggest me any optimization techniques to improve my code and app performance.

Here is my code for deletion of contacts from core data:

+(void)deleteContacts
{
    [[LoadingIndicator currentIndicator]displayActivity:@"Deleting Old contacts"];

    //fetch the data from core data and delete them because you are going to sync again
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSManagedObjectContext *managedObjectContext=[appDelegate managedObjectContext];

    fetchRequest.entity = [NSEntityDescription entityForName:@"PersonEvent" inManagedObjectContext:managedObjectContext];

    NSInteger *contactsIdentifier=1;
    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"sourceflag == %d", contactsIdentifier];


    NSArray * persons = [managedObjectContext executeFetchRequest:fetchRequest error:nil];



    //error handling goes here
    if (persons.count>0) {


        for (NSManagedObject * person in persons) {
            [managedObjectContext deleteObject:person];

        }
    }
    NSError *saveError = nil;
    [managedObjectContext save:&saveError];
    [[LoadingIndicator currentIndicator]displayCompleted:@"Done"];
    [[LoadingIndicator currentIndicator]hide];
    NSLog(@"Finished deleting local contacts..");
}

The time profiler shows me 94.3% time is spent on [managedObjectContext save:&saveError];

Any help would be appreciated

Thanks

vin
  • 1,258
  • 5
  • 20
  • 33

2 Answers2

0

Firstly i want to say "Good Question". And appreciate the things on which you have concerns.

Answer :-

In core data managedObjectContext remains have the all changes in that same object it not update it to the actual database.

So when [managedObjectContext save:&saveError] called it starts updating it to core data database. So You can do optimisation by below way follow it & check the time profile performance.

NSError *saveError = nil;
if (persons.count>0) {


    for (NSManagedObject * person in persons) {
        [managedObjectContext deleteObject:person];
        [managedObjectContext save:&saveError];
    }
}
[[LoadingIndicator currentIndicator]displayCompleted:@"Done"];
[[LoadingIndicator currentIndicator]hide];
NSLog(@"Finished deleting local contacts..");

Hope it helps you ...!

Arpit Kulsreshtha
  • 2,452
  • 2
  • 26
  • 52
  • this will increase Disk IO usage, battery usage. Not a solution definitely. One should run save method on the background thread if operation has too many rows/changes – art-divin Jul 04 '13 at 14:06
  • If i use your code,it takes double the time. [managedObjectContext save:&saveError]; shouldnt be in the for loop. – vin Jul 04 '13 at 14:24
0

Maybe PersonEvent entity has relationships that are configured with Cascade deletion rule? And maybe even objects on the other side of those relationships have similar deletion rules? Core Data will fire all those faults individually.

In this case you should prefetch those relationships when fetching for the objects to delete:

fetchRequest.relationshipKeyPathsForPrefetching
    = @[@"relationshipName",
        @"anotherRelationship",
        @"anotherRelationship.subrelationship"];

If no objects are deleted in a cascade together with PersonEvent, and you just delete a lot of PersonEvent, you may try saving in batches. This will probably not reduce the total time needed to save all the deletions, but it won't lock context, persistent store coordinator, and the store file itself for one huge save.

const NSUInteger kBatchSize = 200;
NSUInteger currentCount = 0;
for (NSManagedObject *person in persons) {
    currentCount++;
    [context deleteObject:person];
    if (currentCount == kBatchSize) {
        currentCount = 0;
        NSError *error;
        BOOL saved = [context save:&error];
    }
}

if (currentCount != 0) {
    NSError *error;
    BOOL saved = [context save:&error];
}
eofster
  • 2,027
  • 15
  • 18