Ben:

I was actually just uncovering some of this stuff myself. In my particular case I am mostly doing inserts so while the KVC stuff is interesting and very well may be useful at some point, it doesn't apply to my current situation.

My problem is that I receive data from a connection and process it in my one worker thread sequentially. After each batch I save the worker thread's MOC and send a bunch of OIDs back to the main thread. I think this is the approved way of doing things. The issues lie in the fact that, depending on several things, batches often end up being rather small which makes saves rather frequent. Last night (morning) after posting I spent some time in shark and save: was burning up >50% of the time in my worker thread. With a little work to coalesce batches and sleep instead of immediately exiting (in hope that a new batch might come in) I've gotten that number down to around 40%. However this is still quite substantial and I'd like to get it down into the 25% range. The trick is just trying to figure out ways to save less frequently, without letting the UI go too stale. One of the biggest performance improvements so far has been to coalesce pending batches into a single larger batch... this makes the sorting behavior of my UI a bit more "chunky" than I'd like, but I think is acceptable as it cuts a second or so off the length to completion of normal searches.

I'm guessing the bugs really should be filed on the documentation since one page on performance of a highly complex API like CD is nowhere near enough. My guess is that documentation doesn't get as many bugs as it should since it is, at the point of the developer filing the bug, no longer a road block and therefore is kind of seen (wrongly) as a waste of time since it is just for the greater good of the dev community not getting your project done.

Thanks for the feedback it was quite helpful. Any thoughts or tricks to reduce the frequency of saving in worker threads would be welcome, but I think I'm now on the right path.

->Ben
--
Ben Lachman
Acacia Tree Software

http://acaciatreesoftware.com

[EMAIL PROTECTED]
740.590.0009



On Mar 30, 2008, at 9:50 PM, Ben Trumbull wrote:
David, Jeff, Ben

There are a few issues here.

First, enough pieces of AppKit and Cocoa Bindings are not thread safe that, even without Core Data, you just can't do this in this particular fashion.

If you want multi-threaded work with the view and controller classes in Cocoa, you'll need to perform your background operations, and communicate back to the main thread (view & controllers) via the run loop. -performSelectorOnMainThread and its friends in NSThread.h are your best bet.

Using a run loop on a background thread and communicating from the main thread to it with the new 10.5 -performSelector... methods is often conceptually simpler (easier to debug) than many other threading patterns.

Sharing a MOC with Cocoa Bindings and a background thread will end in tears. Cocoa Bindings doesn't lock its bound MOC, so you're basically SOL.

Even if it did work, though, it'd be a bad idea. Sharing a MOC means a background thread would still at times block the main thread and SPOB your app.

These 3 points (can't work, doesn't work, shouldn't work) are why the Core Data Programming Guide says don't do this.

This isn't to say what what you intend to accomplish is wrong or undesirable. Quite the contrary. Just that this 'how' is going in the wrong direction.

The Core data programming guide says its best to maintain a separate
managedObjectContext per thread. But this appears to require the data to be written to persistent store to make it work (file). That not reasonable in
my case where I'm adding many objects to an object tree. It takes a
significant amount to time to write it out, negating the benefit of trying
to make the UI seem responsive.

The list archives also have these, which you should read:
<http://lists.apple.com/archives/cocoa-dev/2007/May/msg00222.html>
<http://lists.apple.com/archives/cocoa-dev/2008/Jan/msg01889.html>

It's possible to shuttle pending changes between threads by hand using KVC.

On Tiger, saves are especially expensive as the default behavior was to use a more correct/aggressive version of fsync, specifically fcntl(...,F_FULLFSYNC). This is 100-1000x slower than fsync, which technically is incorrect on nearly all consumer grade hard drives at a hardware level.

On Leopard, we made significant performance optimizations, so the user experience can vary greatly between the two OS's.

If you're inserting a large number of new objects, you really should just batch the operation together, save, and present the user with new objects in the tree view in batches.

On Leopard, in the scenarios under which you can save, you can also use -mergeChangesFromContextDidSaveNotification:

While AppKit & Bindings makes it impossible to share a MOC with a background thread, theoretically all your background threads can share a MOC if you lock and unlock them. Or you could just have 1 background thread processing asynchronous operations. That'd be a lot easier to debug.

You should also use the Debug libraries and Core Data multi- threaded assertions:
<http://lists.apple.com/archives/cocoa-dev/2008/Mar/msg01098.html>

Life's a lot easier when your app halts in gdb as soon as you make a mistake. 'thread apply all bt' is your friend.

Finally, in 4 years no one has filed a bug about this.

If one developer has a problem, it's unfortunate. If three developers have a problem, it's an issue. If two hundred developers have a problem, it's a crisis.

Kinda hard to tell the difference if developers can't be bothered to speak up in the only way that really matters: bugerport.apple.com

Feature requests, performance problems, and enhancement suggestions are all "bugs"

_______________________________________________

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 [EMAIL PROTECTED]

Reply via email to