Does Core Data have a serious problem?
Does Core Data have a serious problem?
- Subject: Does Core Data have a serious problem?
- From: Ben Trumbull <email@hidden>
- Date: Sat, 5 May 2007 17:39:16 -0700
1. Core Data is not inherently thread safe
Core Data is inherently designed for scalable concurrency.
Core Data is used in many multi-threaded Cocoa applications, from the
background fetching example in /Developer/Examples/CoreData to
pro-apps like Aperture.
The protocol it uses for NSManagedObject and NSManagedObjectContext
is called thread confinement. NSManagedObjectIDs are immutable.
NSPersistentStoreCoordinator implements NSLocking.
NSManagedObjectModel (and friends) are immutable after being used to
initialize an NSPersistentStoreCoordinator.
You may also find some of my previous cocoa-dev postings useful, as
they include details about copy-on-write data sharing between
contexts, etc.
If any of this is unclear, I highly recommend "Java Concurrency in
Practice" by Brian Goetz, et al 2006.
"Java Concurrency in Practice" is focused precisely on real world
engineering issues, and I strongly recommend it for, well, everyone.
The techniques and problems described are directly relevant to C,
C++, and Objective-C.
<http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601/ref=pd_bbs_sr_1/104-9065426-0083159?ie=UTF8&s=books&qid=1175986065&sr=8-1>
and while we're on the subject of reading material, if you've ever
wondered *why* multi-threaded programming is such as pain, here's a
great article by Edward Lee from UC Berkeley:
<http://www.computer.org/portal/site/computer/menuitem.5d61c1d591162e4b0ef1bd108bcd45f3/index.jsp?path=computer/homepage/0506&file=cover.xml&xsl=article.xsl>
2. To share new objects or object changes/deletions to other
contexts, one has to save the context
Sharing new objects does require saving. For most applications, this
is occasionally inconvenient, but not problematic.
Changes and deletions can be exposed to other context before saving,
and you can even let Core Data's built in optimistic concurrency
control clean up the fall out.
3. This can take a while (especially with an SQL store)
The SQLite store does partial updates (being a relational database)
and is much much faster than your alternatives once the data set is a
respectable size. For small amounts of data, any of the stores will
do well.
4. The context seems to lock the store coordinator during a save!!!
As the only thing that remotely makes sense, yes, it does. You're
welcome to draft out the alternatives, and see what happens when
multiple threads, and multiple processes, start intermingling saves,
fetches, undos, etc.
If you would like to trade memory for more concurrency, you can use
multiple store coordinators.
5. The data of an object is not automatically obtained from the store
executeFetchRequest always obtains the data from the store.
Relationships off the objects you explicitly fetch are loaded lazily.
You're free to trade memory for performance by more eagerly fetching
additional objects.
6. The context locks the store coordinator during the firing of a fault
This is currently true.
So taken all this together: When your app does a lengthy save
operation in a background context, it can hang pretty easily
(spinning beach ball) while the save operation is under way.
You can
(1) save in smaller batches, to prevent starving the UI thread,
(2) prefetch more of the data that the UI thread needs,
(3) save on an entirely separate coordinator.
To any listening Apple engineer:
Do you want me to file this as a bug?
If you have a Shark sample that demonstrates a performance problem in
Core Data, when used correctly, then absolutely file a bug report.
Performance bugs are still bugs.
P.S.: Locks are like tanks
And being on the wrong end of the turret is unhealthy.
The ridiculous fish article you reference is an excellent example of
something that is extremely precise and yet wildly inaccurate.
Under some 99% of circumstances, *uncontended* locks are extremely
fast, extremely powerful, and their getting stuck is a crucial
debugging feature that illuminates a bug in your code.
Memory barriers are not a suitable general replacement for locks.
Memory barriers are an extremely specialized, extremely advanced
tool. Even the high end server guys working on machines with
hundreds of CPUs treat memory barriers with caution. One
presentation from engineers working on such a device is here:
<http://developers.sun.com/learning/javaoneonline/2006/coolstuff/TS-5354.pdf>
It describes how they improved concurrency by 54x. Not a single one
of their optimizations is an explicit memory barrier.
If locks are like tanks, then memory barriers are like nukes.
Everybody wants to own them, and nobody in their right mind wants to
use them.
Try using Shark, both with and without the All Thread States sampling
mode. Focus on the issues that are performance bottlenecks in
practice.
Seeing as I have a list of all the contended locks I've come across
on the system, and you aren't complaining about any of them (yet), I
would suggest it's much too early to be worrying about memory
barriers.
--
-Ben
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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