On Aug 20, 2009, at 2:34 AM, Ruotger Skupin wrote:


Am 19.08.2009 um 22:00 schrieb Ben Trumbull:

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 ?
I'm not using a predicate for the first fetch. (Ok, I have learned now, I should do so.)

Okay, but what was the predicate you were passing to filteredArrayUsingPredicate: ?

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).
Yes I do some on-the-fly filtering which depends on other objects. (Ok, lesson learned: Bad idea)

Dynamic filtering isn't necessarily bad. The goal is always to perform the least amount of I/O and consume the least amount of memory. This produces the best performance.

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.
So, would it be better to perform the on-the-fly filtering calculation every time the object changes and put flags in the root object? Then fetch with a predicate testing these flags? Probably. (model change! yay!)

Uhm, I think we're getting way ahead of ourselves. That's probably serious overkill for the problem you're currently facing.

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.
That's what I'm doing now because the most common use case is: I need almost everything. So the approximation is: I fetch everything and filter out some objects.

Well, we can provide better suggestions with the actual filtering predicate you're using. But the primary point here is that you're NOT fetching everything. You're only fetching the objects on one side of a relationship, but filtering based on information across a relationship.

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.
The subsets depend on the data of the objects. (Smart Folders)

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.
Isn't all text Unicode? I don't understand. This shouldn't be a special case. But I will have a look at the sample.

You can HAVE as much Unicode text as you want. That's just bytes. But performing regex or CONTAINS searches on Unicode text is very expensive.

In my case I'd guess that at least half of the objects contain unicode strings (international names and addresses). What I want to say: write anything in German or French and you end up with Unicode.

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.

As stated before I need almost all data anyway. Is there a way to bulk-load the whole database into mem in one go? That's not what sql is about, is it?

setRelationshipKeyPathsForPrefetching

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.
Ok, will try to do that.

Another question: I'm using Garbage Collection. Should I look out for something special there? Keep managed objects on purpose? Letting them go as soon as possible?


One thing at a time. Add the appropriate prefetching to your fetch request and then reprofile the app.

- 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