re: Performance degrades dramatically in [NSManagedObjectContext executeFetchRequest:error:]
re: Performance degrades dramatically in [NSManagedObjectContext executeFetchRequest:error:]
- Subject: re: Performance degrades dramatically in [NSManagedObjectContext executeFetchRequest:error:]
- From: Ben Trumbull <email@hidden>
- Date: Sun, 8 Mar 2009 16:55:54 -0700
Oleksiy,
NSManagedObjectContext tries to keep the fetch results in sync with
the pending unsaved changes you've made. So the more inserted,
updated, and deleted objects you have that might match the entity
you're fetching against, the longer it can take to filter unsaved
changes.
You can issue the fetch against another, clean, MOC and pass the
results back the the primary MOC via objectIDs, or you can save more
frequently.
- Ben
Hello All!
(this is the same in plain text)
Summary: It looks like [NSManagedObjectContext
executeFetchRequest:error:] starts to evaluate a predicate
([NSPredicate evaluateWithObject:]) with objects that was not
requested and was not fetched from
a database.
Our application makes prefetching of CoreData entities with
relationships like
NSFetchRequest* requestRelatedTags = [[[NSFetchRequest alloc] init]
autorelease];
[requestRelatedTags setEntity:[NSEntityDescription entityForName :
kFSIValueElementA inManagedObjectContext : [md
managedObjectContext ]] ];
[requestRelatedTags setFetchLimit: 1000000 ];
NSPredicate * predicate = [ NSPredicate predicateWithFormat: @"(self
IN %@)",[items valueForKey: @"objectID"]];
[requestRelatedTags setPredicate:predicate];
[requestRelatedTags setRelationshipKeyPathsForPrefetching :
[ NSArray arrayWithObjects: @"tags", nil]];
[requestRelatedTags setReturnsObjectsAsFaults: true];
items0_ = [[md managedObjectContext] executeFetchRequest :
requestRelatedTags error: nil];
where "items" is an array of 100 NSManagedObjects, "tags" is to-many
relationship of the kFSIValueElementA entity with inverse to-one
relationship.
At start this code works quickly and takes fixed amount of time
(0.03-0.04 sec) every time. But at some point it starts to work very
slowly taking more and more time. Instruments shows that it fetches
100 objects
every time from a database. But Shark shows that it uses
[NSPredicate evaluateWithObject:] more and more times. To be
precise, it invokes [NSPredicate evaluateWithObject:] 100 times more
every time.
[NSPredicate evaluateWithObject:] is invoked every time from
[NSManagedObjectContext executeFetchRequest: error:].
We added logging to [NSPredicate evaluateWithObject:] and we see
that it is evaluated on objets that was not requested by the fetch
request and was not fetched from the SQLite database. Thus this is a
bug
in [NSManagedObjectContext executeFetchRequest:error:]. It should
not filter objects that was not.
Does anybody have any ideas how to solve this problem?
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden