ios - Sqlite or Core Data to update more then 50000 records -
i'm using coredata project. when api returns 54000 objects app need update, user has wait 2 hours. it's major problem current project , thinking use sqlite , not using coredata anymore update thousands of objects.
is right decision use sqlite or there suggestion coredata? can't decide. great. thank you.
here doing:
nsmanagedobjectcontext *privateobjectcontext = [appdelegate appdelegate].privatemanagedobjectcontext; [privateobjectcontext performblock:^{ int = 1; (nsdictionary *item in itemlist) { i++; [fetchrequest setpredicate:[nspredicate predicatewithformat: @"itemid == %@",[item objectforkey:@"item_id"] ]]; nserror *error; nsmutablearray *inventories = [[nsmutablearray alloc]initwitharray: [privateobjectcontext executefetchrequest:fetchrequest error:&error]]; itemmanagedobject *itemmo; if(inventories.count){ itemmo = inventories.firstobject; }else{ itemmo = [nsentitydescription insertnewobjectforentityforname:@"itemobject" inmanagedobjectcontext:privateobjectcontext]; } [itemmo preparewithdictionary:item]; } nserror *error; if (![privateobjectcontext save:&error]) { completionhandler(no); } }
2 hours long. that's weird.
yet can massage code having core data less work. less work.
- perform single fetch request instead of 54k fetch requests
- don't call managed object property setter when property value not change, no object unnecessarily flagged dirty, , core data not have perform costly useless update of object when "save" method invoked.
this dramatically reduce amount of work performed core data, , performance of application.
the second point easy, verbose: compare each individual property values dictionary values before calling setters.
the first point requires algorithm change:
perform single fetch request, sorted id (with [nsfetchrequest setsortdescriptors:])
sort dictionaries id (with [nsarray sortedarray...])
synchronize 2 sorted lists (it paramount both lists sorted):
nsenumerator *itemmoenum = [itemmos objectenumerator]; nsenumerator *dicenum = [dictionaries objectenumerator]; itemmanagedobject *itemmo = [itemmoenum nextobject]; nsdictionary *itemdic = [dicenum nextobject]; while (itemdic) { nscomparisonresult comparison = itemmo ? [itemdic[@"item_id"] compare:itemmo.itemid] : nsorderedascending; switch (comparison) { case nsorderedsame: // id present in both lists: update [itemmo preparewithdictionary:itemdic]; itemmo = [itemmoenum nextobject]; itemdic = [dicenum nextobject]; break; case nsorderedascending: { // id present in dictionaries: create itemmo = [nsentitydescription insertnewobjectforentityforname:@"itemobject" inmanagedobjectcontext:privateobjectcontext]; [itemmo preparewithdictionary:itemdic]; itemdic = [dicenum nextobject]; } break; case nsordereddescending: // id present in managed object: delete or nothing itemmo = [itemmoenum nextobject]; break; } } while (itemmo) { // id present in managed object: delete or nothing itemmo = [itemmoenum nextobject]; }
and save.
finally, maybe sqlite faster (see https://github.com/groue/grdb.swift/wiki/performance attempt @ comparing performance of core data sqlite libraries).
but sqlite won't turn slow algorithm fast one.
Comments
Post a Comment