CoreData - Fast Deletion Of Thousands Of ManagedObjects?
-
I have a tableview representing managed objects. If I select all the
managed objects e.g.10,000, and delete them from the
managedObjectContext, there is a long delay e.g. 30 seconds.
Is there a way to delete large numbers of objects from a context
quickly and avoid the spinning beach ball? I don't really want to
have to delete the objects in a background thread, or put up a panel
saying 'Deletion in progress'.
My managed objects have relationships with nullify and cascade
deletion rules. My deletion code looks something this:
id undoManager = [[context undoManager] retain];
[context setUndoManager:nil];
while (obj = [enumerator nextObject]) {
[context deleteObject:obj];
}
[context setUndoManager:[undoManager autorelease]];
Appreciate any tips. Thanks.
--Simon -
Which backing store are you using for CoreData, and have you tried
switching it out for a different one?
SQLite has been entirely too slow for my tastes when trying to import
a few tens of thousands of records, so I've switched back to using
XML for most of my apps; I can generate a flat file of the 34k or so
records in a few seconds, whereas SQLite was going to take an hour or
more to import them.
-justinb
On Dec 20, 2005, at 8:32 AM, Simon Liu wrote:> I have a tableview representing managed objects. If I select all the
> managed objects e.g.10,000, and delete them from the
> managedObjectContext, there is a long delay e.g. 30 seconds.
>
> Is there a way to delete large numbers of objects from a context
> quickly and avoid the spinning beach ball? I don't really want to
> have to delete the objects in a background thread, or put up a panel
> saying 'Deletion in progress'.
>
> My managed objects have relationships with nullify and cascade
> deletion rules. My deletion code looks something this:
>
> id undoManager = [[context undoManager] retain];
> [context setUndoManager:nil];
>
> while (obj = [enumerator nextObject]) {
> [context deleteObject:obj];
> }
>
> [context setUndoManager:[undoManager autorelease]];
>
> Appreciate any tips. Thanks.
> --Simon
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Cocoa-dev mailing list (<Cocoa-dev...>)
> Help/Unsubscribe/Update your Subscription:
> http://lists.apple.com/mailman/options/cocoa-dev/justinb%
> 40shipwreckbeads.com
>
> This email sent to <justinb...> -
On Dec 20, 2005, at 11:30 AM, Justin Burns wrote:> SQLite has been entirely too slow for my tastes when trying to
> import a few tens of thousands of records, so I've switched back to
> using XML for most of my apps; I can generate a flat file of the
> 34k or so records in a few seconds, whereas SQLite was going to
> take an hour or more to import them.
See <http://developer.apple.com/documentation/Cocoa/Conceptual/
CoreData/Articles/cdImporting.html#//apple_ref/doc/uid/TP40003174>
and <http://www.cocoabuilder.com/archive/message/cocoa/
2005/12/20/152920>.
If data importing is taking as long as you state, it is likely that a
different pattern would improve things substantially.
mmalc -
On Dec 20, 2005, at 11:30 AM, Justin Burns wrote:> SQLite has been entirely too slow for my tastes when trying to
> import a few tens of thousands of records
How did you structure this import? Does it look anything like this
pseudocode?
get an old-style record
see if a matching record already exists by issuing a fetch
if a matching record doesn't exist:
create a new record
set its attributes
issue a fetch to find related records
set its relationships
I refer to this as a "find-or-create" pattern and it offers many
opportunities for optimization. The most important optimizations
here are to cut down on or eliminate unnecessary fetches, and to
introduce intermediate autorelease pools to prevent unbounded growth
of your working set.
-- Chris -
I'm using a SQLite store which the CoreData docs claim to be the fastest store.
Regardless of the store type, there doesn't seem to be a way to delete
a large number of objects quickly, even when only invoking
-deleteObject: on a context, and leaving the changes uncommitted.
On 12/20/05, Justin Burns <justinb...> wrote:> Which backing store are you using for CoreData, and have you tried
> switching it out for a different one?
>
> SQLite has been entirely too slow for my tastes when trying to import
> a few tens of thousands of records, so I've switched back to using
> XML for most of my apps; I can generate a flat file of the 34k or so
> records in a few seconds, whereas SQLite was going to take an hour or
> more to import them.
>
> -justinb
>
> On Dec 20, 2005, at 8:32 AM, Simon Liu wrote:
>
>> I have a tableview representing managed objects. If I select all the
>> managed objects e.g.10,000, and delete them from the
>> managedObjectContext, there is a long delay e.g. 30 seconds.
>>
>> Is there a way to delete large numbers of objects from a context
>> quickly and avoid the spinning beach ball? I don't really want to
>> have to delete the objects in a background thread, or put up a panel
>> saying 'Deletion in progress'.
>>
>> My managed objects have relationships with nullify and cascade
>> deletion rules. My deletion code looks something this:
>>
>> id undoManager = [[context undoManager] retain];
>> [context setUndoManager:nil];
>>
>> while (obj = [enumerator nextObject]) {
>> [context deleteObject:obj];
>> }
>>
>> [context setUndoManager:[undoManager autorelease]];
>> -
Might try to check the amount of relationships that need to deleted
and nullified by the original delete.
It might be complex, in which case there is not much to do except
hope for performance update or
maybe change your object model...
One thing, that *may* be slightly fast would be to call the raw C
array and cycle through that like: (THIS IS UNTESTED!!)
///////////////////////////////
id undoManager = [[context undoManager] retain];
int numberOfObjectsToDelete = [objects count];
id arrayOfObjectsToDelete = [objects
getObjects:&arrayOfObjectsToDelete];
int currentObject = 0;
while (currentObject =0; currentObject < objectsToDelete;
currentObject ++)
{
[context deleteObject:objectsToDelete[currentObject] ];
}
[context setUndoManager:[undoManager autorelease]];
//////////////////////////////// Might give you 3 or 4 seconds
faster... thats
Maybe the NSManagedContext should have a - (BOOL)deleteObjects:
(NSArray *)objects method, that way
the context can analyze the relationships in relation to eachother
and speed the delete....
Simon Liu wrote:> I have a tableview representing managed objects. If I select all the
> managed objects e.g.10,000, and delete them from the
> managedObjectContext, there is a long delay e.g. 30 seconds.
>
> Is there a way to delete large numbers of objects from a context
> quickly and avoid the spinning beach ball? I don't really want to
> have to delete the objects in a background thread, or put up a panel
> saying 'Deletion in progress'.
>
> My managed objects have relationships with nullify and cascade
> deletion rules. My deletion code looks something this:
>
> id undoManager = [[context undoManager] retain];
> [context setUndoManager:nil];
>
> while (obj = [enumerator nextObject]) {
> [context deleteObject:obj];
> }
>
> [context setUndoManager:[undoManager autorelease]];
>
> Appreciate any tips. Thanks.
> --Simon
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Cocoa-dev mailing list (<Cocoa-dev...>)
> Help/Unsubscribe/Update your Subscription:
> http://lists.apple.com/mailman/options/cocoa-dev/<pyunpyun...>
>
> This email sent to <pyunpyun...> -
On Dec 20, 2005, at 7:21 PM, <pyunpyun...> wrote:> Might try to check the amount of relationships that need to deleted
> and nullified by the original delete.
> It might be complex, in which case there is not much to do except
> hope for performance update or
> maybe change your object model...
> One thing, that *may* be slightly fast would be to call the raw C
> array and cycle through that like:
Iterating over the C array will have an insignificant effect here.
There are several possible problems, including one known issue with
key-value observing notifications. The first step would be to ensure
that faults are not being fired as described in <http://
www.cocoabuilder.com/archive/message/cocoa/2005/12/20/152920> (see,
for example, Batch Faulting at <http://developer.apple.com/
documentation/Cocoa/Conceptual/CoreData/Articles/cdFetching.html#//
apple_ref/doc/uid/TP40002484-DontLinkElementID_19>). I hope I may be
able to address other issues soon.
mmalc -
mmalcolm crawford wrote:>> documentation/Cocoa/Conceptual/CoreData/Articles/cdFetching.html#//
> On Dec 20, 2005, at 7:21 PM, <pyunpyun...> wrote:
>
>
>> Might try to check the amount of relationships that need to
>> deleted and nullified by the original delete.
>> It might be complex, in which case there is not much to do except
>> hope for performance update or
>> maybe change your object model...
>> One thing, that *may* be slightly fast would be to call the raw C
>> array and cycle through that like:
>>
>
> Iterating over the C array will have an insignificant effect here.
> There are several possible problems, including one known issue with
> key-value observing notifications. The first step would be to
> ensure that faults are not being fired as described in <http://
> www.cocoabuilder.com/archive/message/cocoa/2005/12/20/152920> (see,
> for example, Batch Faulting at <http://developer.apple.com/> apple_ref/doc/uid/TP40002484-DontLinkElementID_19>). I hope I may
> be able to address other issues soon.
>
I was thinking that according tot he above article saying: "You
should avoid executing multiple requests if you can instead combine
them into a single request that will return all the objects you
require."
How about the same thing for deletion? - (void)deleteObjects:(NSArray
*)objects error:(NSError **)error ?
Then coredata can optimize the deletion process?> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Cocoa-dev mailing list (<Cocoa-dev...>)
> Help/Unsubscribe/Update your Subscription:
> http://lists.apple.com/mailman/options/cocoa-dev/<pyunpyun...>
>
> This email sent to <pyunpyun...>
>


