2009-11-21 19:44:27 CoreData Key Paths
In reference to this fine article by Matt Gallagher, I did some numerical investigations on just the test to retrieve the full set of all names of projects for a given company.

I made a loop that added 100 companies with random names at each iteration and a random number of projects, between 1 and 5, each with a random name, and did this 100 times, creating 10,000 companies w/ about 30,000 projects. Each run was done with a clean database. I timed these following test routines to grab the project names, once per company. Very quick-n-dirty.
( objc )
  1  - (void)test1:(NSArray *)allCompanies {
2 for( Company *company in allCompanies )
3 [company valueForKeyPath:@"projects.name"];
4 }
5 - (void)test2:(NSArray *)allCompanies {
6 for( Company *company in allCompanies )
7 [company.projects valueForKey:@"name"];
8 }
9 - (void)test3:(NSArray *)allCompanies {
10 for( Company *company in allCompanies ) {
11 NSMutableSet *result = [NSMutableSet set];
12 for (Project *project in company.projects) {
13 NSString *value = project.name;
14 if (value)
15 [result addObject:value];
16 }
17 }
18 }
19 - (void)test4:(NSArray *)allCompanies {
20 for( Company *company in allCompanies ) {
21 NSSet *projects = company.projects;
22 NSMutableSet *result = [NSMutableSet setWithCapacity:[projects count]];
23 for (Project *project in projects) {
24 NSString *value = project.name;
25 if (value)
26 [result addObject:value];
27 }
28 }
29 }
30 - (void)test5:(NSArray *)allCompanies {
31 for( Company *company in allCompanies )
32 [company.projects objectValuesForProperty:@selector(name)];
33 }

Test 5 uses Matt's -objectValuesForProperty: category on NSSets.

I saved the outputs to textfiles and plotted them (using matplotlib) to produce this:



Key:

  • test1 = green
  • test2 = blue
  • test3, test4, test5 = the other colors that are basically all the same line

If you read Matt's article, you'll note that I didn't see the differences that Matt was able to tease out between tests 3 and 4, but I'm sure it's a function of our different, um, functions. Not sure why. Perhaps this test is just too simple or small.

I was impressed at how much faster the test ran in test2, just swapping out the line [company valueForKeyPath:@"projects.name"] for [company.projects valueForKey:@"name"].

My test probably has all kinds of problems with it that don't show off the advantages well enough, and I probably should have written something that looks up, say, employee names, and maybe that's the next test I'll make. This is interesting enough for now to post.
Leave a comment