Nested Managed Object Contexts remove the benefit of fetchBatchSize

Originator:graham.dennis
Number:rdar://11235622 Date Originated:2012-04-12
Status:Open Resolved:
Product:iOS SDK Product Version:iOS 5.1
Classification:Performance Reproducible:Always
 
Summary:

Using Nested NSManagedObjectContexts removes the positive benefits of using a fetchBatchSize on NSFetchRequest for SQL data stores. 

When using a single NSManagedObjectContext, just the primary keys sorted by the sort descriptors are fetched first, and then fetchBatchSize worth of objects are fetched at a time.  Using nested NSManagedObjectContext's, the parent NSManagedObjectContext fetches all of the columns, and then presumably uses this data to fulfil the child context's requests.

Steps to Reproduce:

1. Build the attached project either for Simulator or a device.
2. Run it twice with the -com.apple.CoreData.SQLDebug 1 command line argument. The first time the performance figures are off probably due to disk caching.
3. The time for the Single Context case is faster than the nested context case.

Expected Results:

The time taken for the Nested Context case is about the same or only slightly slower than the single Context case.

Actual Results:

The Nested Context case is about 5x slower for this case.  Below are the output from an iPhone 4:
2012-04-12 23:21:26.449 NestedMOCTest[1975:707] ******* Single Context test ********
2012-04-12 23:21:26.477 NestedMOCTest[1975:707] CoreData: annotation: Connecting to sqlite database file at "/var/mobile/Applications/E8AC836C-40C5-462C-A1A8-93EC30F0C90C/NestedMOCTest.app/NestedMOCTest.sqlite"
2012-04-12 23:21:26.485 NestedMOCTest[1975:707] CoreData: sql: SELECT Z_VERSION, Z_UUID, Z_PLIST FROM Z_METADATA
2012-04-12 23:21:26.497 NestedMOCTest[1975:707] CoreData: sql: SELECT 0, t0.Z_PK FROM ZROW t0 ORDER BY t0.ZANATTRIBUTE
2012-04-12 23:21:26.614 NestedMOCTest[1975:707] CoreData: annotation: sql connection fetch time: 0.1113s
2012-04-12 23:21:26.619 NestedMOCTest[1975:707] CoreData: annotation: total fetch execution time: 0.1226s for 10000 rows.
2012-04-12 23:21:26.628 NestedMOCTest[1975:707] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZANATTRIBUTE FROM ZROW t0 WHERE  t0.Z_PK IN  (?,?,?,?,?,?,?,?,?,?)  ORDER BY t0.ZANATTRIBUTE LIMIT 10
2012-04-12 23:21:26.637 NestedMOCTest[1975:707] CoreData: annotation: sql connection fetch time: 0.0082s
2012-04-12 23:21:26.642 NestedMOCTest[1975:707] CoreData: annotation: total fetch execution time: 0.0145s for 10 rows.


For this single context case we see that 0.1226s + 0.0145s were taken to get the first batch from the store. Just the Primary key was fetched first.

2012-04-12 23:21:26.648 NestedMOCTest[1975:707] ******* Nested Context test ********
2012-04-12 23:21:26.655 NestedMOCTest[1975:707] CoreData: annotation: Connecting to sqlite database file at "/var/mobile/Applications/E8AC836C-40C5-462C-A1A8-93EC30F0C90C/NestedMOCTest.app/NestedMOCTest.sqlite"
2012-04-12 23:21:26.662 NestedMOCTest[1975:707] CoreData: sql: SELECT Z_VERSION, Z_UUID, Z_PLIST FROM Z_METADATA
2012-04-12 23:21:26.672 NestedMOCTest[1975:707] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZANATTRIBUTE FROM ZROW t0 ORDER BY t0.ZANATTRIBUTE
2012-04-12 23:21:27.530 NestedMOCTest[1975:707] CoreData: annotation: sql connection fetch time: 0.6705s
2012-04-12 23:21:27.536 NestedMOCTest[1975:707] CoreData: annotation: total fetch execution time: 0.8637s for 10000 rows.

For this nested context case we see that all data was fetched from the store and it took 0.6705s, 5x slower than the single context case.

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!