when fetching about 5000 objects from an sql store, Core Data is very
slow the very first time after a boot. When running the app the first
time it takes 50 to 90 seconds and when starting it the second time it
is well below one second.

Properly done, you could fetch 5000 objects on an original iPhone in a couple of seconds (or even less, depending on the NSFetchRequest options). On a Mac Pro, your performance is off by two orders of magnitude. If you wanted a result set, but didn't need all of it at once, you could use setBatchSize and handle about 3 million rows per second on a Mac Pro.

Have you profiled your application ? Have you run Instruments on your app with the Core Data template ? It'll provide Core Data specific information about faulting, fetching and saving which pairs well with the more general CPU sampler.

According to shark basically nothing plus some time spend in faults.
Shark is useless when perf-debugging Core Data.

Shark is very good at telling you where you are doing something expensive. Shark has just given you really valuable information (too many faults being tripped) and where in your code you are doing this expensive thing. Instead of describing that as useless, perhaps you should consider reducing the number of faults being tripped ...

I debugged it with some Snow Leopard magic and found out, that firing
faults is very slow the first time after boot. When I use -[NSArray
filteredArrayUsingPredicate:] the fault firing is killing me.


What's the predicate you are using ?

You're almost certainly filtering in memory after fetching only a subset of the data needed to perform your in memory filtering (specifically, only the source entity and not its relationships). Since you didn't fetch the related objects, Core Data goes and retrieves them on demand. However, mind reading is technically challenging, and Plan B, retrieving the related objects one at a time, is a rather inefficient I/O pattern.

It would be vastly faster to filter the data in the database using a predicate on the fetch request. If that's not possible, then you should use a fetch request predicate that approximates what you need, and filter those results more precisely in memory. Like a bounding rect in views. If you have already fetched the objects, but want to identity different subsets, you can use objectID fetch results to simply identify the matching objects without pulling back all the row data.

Complex locale aware Unicode text queries can be slow. If you find yourself spending time with such a query, you should consider some of the techniques shown in the DerivedProperty example available on ADC.

What is going on here?

Typically, apps that launch slowly once, and then run quickly afterwards are doing far too much I/O. On successive launches, the kernel has cached most of the data, so instead of doing to-disk I//O the app is doing to-kernel-memory I/O.

The most common problem in Core Data apps is when people allow faulting to lazily fetch data one row at a time, even when the app needs all the data immediately. They should prefetch the related objects with the original fetch request by setting the prefetching keypaths.

Have you read through the Core Data Programming Guide's chapter on Performance ?

<https://developer.apple.com/documentation/Cocoa/Conceptual/CoreData/Articles/cdPerformance.html#//apple_ref/doc/uid/TP40003468 >

So I recoded it to fetch everything upfront with [fetchRequest setReturnsObjectsAsFaults:NO];

This isn't solving the problem you expect. You'll want to use prefetching and should read the programming guide.

Pre-fetching: not tried
But if I understand the document right it's just a special case of
Batch Faulting and I don't see any faults fired since I use Batch
Faulting anyway

No, prefetching is not a special case of batch faulting. Batch faulting is about taking N objects (or objectIDs) and telling Core Data "I want all of these, now". Prefetching is about telling Core Data "I want the objects that match this fetch request, plus all of their related friends X and Y.Z"

- Ben

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to