I'm wondering if anyone has some insight into what would perform better: doing a core data fetch or looking for the file on disk.
The situation I'm in is downloading records and each record has an image tied to it. But different records can have the same image so I don't want to download the image twice. I'm saving the images to disk and using an NSManagedObject to save the web url and the local file path.
To avoid making another network call I can
A: Perform a core data fetch to see if I have the image already based on the web url
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([Image class])];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"web_url == %@", myRecord.image_url];
B: Look for the image data on disk from the local file path
NSFileManager *fileManager = [NSFileManager defaultManager];
NSData *photoData = [fileManager contentsAtPath:myRecord.photo_path];
Additionally is there something in Instruments that would allow me to time these? It would be a handy tool to know how to use in the future. Thanks.
I finally got around to testing this with the help of from a user submitted Macro for Measuring Execution Time in this NSHipster article http://nshipster.com/reader-submissions-new-years-2013/.
The code being tested was as follows
__block NSData *photoData;
const char *caller = "filemanager";
MVComputeTimeWithNameAndBlock(caller, ^{
NSFileManager *fileManager = [NSFileManager defaultManager];
photoData = [fileManager contentsAtPath:[self createLocalFilePath:myRecord.photo_path]];
});
caller = "coredata";
MVComputeTimeWithNameAndBlock(caller, ^{
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([Image class])];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"web_url == %@", myRecord.image_url];
NSError *error;
NSArray *arr = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
if([arr count]){
Image *photo = arr[0];
}
});
2013-01-25 14:31:06.359 FormulaOne[26554:12b03] filemanager - Time Running is: 0.000325 2013-01-25 14:31:06.359 FormulaOne[26554:12b03] coredata - Time Running is: 0.000491 2013-01-25 14:31:11.958 FormulaOne[26554:12b03] filemanager - Time Running is: 0.000178 2013-01-25 14:31:11.959 FormulaOne[26554:12b03] coredata - Time Running is: 0.000417 2013-01-25 14:31:14.840 FormulaOne[26554:12b03] filemanager - Time Running is: 0.000187 2013-01-25 14:31:14.841 FormulaOne[26554:12b03] coredata - Time Running is: 0.000421 2013-01-25 14:33:10.869 FormulaOne[26554:12b03] filemanager - Time Running is: 0.000193 2013-01-25 14:33:10.870 FormulaOne[26554:12b03] coredata - Time Running is: 0.000540 2013-01-25 14:33:13.087 FormulaOne[26554:12b03] filemanager - Time Running is: 0.000170 2013-01-25 14:33:13.088 FormulaOne[26554:12b03] coredata - Time Running is: 0.000392
I switched it over to
int count = [[self managedObjectContext] countForFetchRequest:fetchRequest error:&error];
because I don't actually need the object, I just need to know of its existence. The timing was actually worse.
2013-01-25 14:36:27.760 FormulaOne[28209:12b03] filemanager - Time Running is: 0.000346 2013-01-25 14:36:27.761 FormulaOne[28209:12b03] coredata - Time Running is: 0.000601 2013-01-25 14:36:29.978 FormulaOne[28209:12b03] filemanager - Time Running is: 0.000182 2013-01-25 14:36:29.979 FormulaOne[28209:12b03] coredata - Time Running is: 0.000479 2013-01-25 14:36:31.585 FormulaOne[28209:12b03] filemanager - Time Running is: 0.000265 2013-01-25 14:36:31.586 FormulaOne[28209:12b03] coredata - Time Running is: 0.000400 2013-01-25 14:36:34.923 FormulaOne[28209:12b03] filemanager - Time Running is: 0.000307 2013-01-25 14:36:34.924 FormulaOne[28209:12b03] coredata - Time Running is: 0.001055 2013-01-25 14:36:36.038 FormulaOne[28209:12b03] filemanager - Time Running is: 0.000318 2013-01-25 14:36:36.040 FormulaOne[28209:12b03] coredata - Time Running is: 0.000740