Reputation: 143
So here's my problem, I'm brand new to iOS's CoreData, so I'm not really sure how to optimize, but I've seen a lot of the other questions here, and I've tried to optimize as best as I could, but for some reason, it still takes almost 5 seconds to fetch 100 rows! here's the code where it's being called:
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[self titles:searchText];
}
-(NSArray *)titles:(NSString *)toMatch
{
NSMutableArray * retval = [[NSMutableArray alloc] init];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if(toMatch.length>2)
{
NSString *LabelText =toMatch;
NSString *compareString = @"";
for (int i = 0; i<LabelText.length; i++)
{
int letter = [LabelText characterAtIndex:i];
NSString *blah;
if(letter<100)
{
blah = [NSString stringWithFormat:@"0"];
blah = [blah stringByAppendingFormat:@"%d", letter];
}
else
blah = [NSString stringWithFormat:@"%d", letter];
compareString= [compareString stringByAppendingString:blah];
compareString = [compareString stringByAppendingString:@","];
}
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
NSPredicate *predicate;
if ([defaults boolForKey:@"FLS"])
predicate = [NSPredicate predicateWithFormat:@"first_letter_start BEGINSWITH %@", compareString];
else
predicate = [NSPredicate predicateWithFormat:@"first_letter_start CONTAINS %@", compareString];
[request setPredicate:predicate];
[request setFetchLimit:100];
[request setFetchBatchSize:1];
[request setPropertiesToFetch:[NSArray arrayWithObject:@"gurmukhi"]];
[request setReturnsObjectsAsFaults:NO];
NSError *error;
NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:request error:&error];
for (Gurbani *shabad in fetchedObjects)
{
[retval addObject:shabad.gurmukhi];
}
searchResults = retval;
[searchResultsTable reloadData];
}
return retval;
};
and here's the log after putting in the debug arguments:
2013-01-11 18:04:57.195 GurbaniKhoj[2833:907] CoreData: sql: pragma cache_size=200
2013-01-11 18:04:57.199 GurbaniKhoj[2833:907] CoreData: sql: SELECT Z_VERSION, Z_UUID, Z_PLIST FROM Z_METADATA
2013-01-11 18:05:01.139 GurbaniKhoj[2833:907] CoreData: sql: SELECT 0, t0.Z_PK FROM ZSHABAD t0 WHERE NSCoreDataStringSearch( t0.ZFIRST_LETTER_START, ?, 8, 0) LIMIT 100
2013-01-11 18:05:06.705 GurbaniKhoj[2833:907] CoreData: annotation: sql connection fetch time: 5.5652s
2013-01-11 18:05:06.707 GurbaniKhoj[2833:907] CoreData: annotation: total fetch execution time: 5.5682s for 92 rows.
What's going on? And what can I do to make this go faster?
EDIT: one more thing I noticed is that this speed isn't consistent. for some queries it's 5.5 seconds, for others it's 1.8. I have no idea what's causing the fluctuation.
EDIT 2: Figured out my indexes weren't being created. created a versioned data model, made sure they were indexed, and now This is what the log looks like
2013-01-15 03:06:29.671 GurbaniKhoj[1212:907] CoreData: sql: SELECT 0, t0.Z_PK FROM ZSHABAD t0 WHERE NSCoreDataStringSearch( t0.ZFIRST_LETTER_START, ?, 8, 0) LIMIT 100
2013-01-15 03:06:31.130 GurbaniKhoj[1212:907] CoreData: annotation: sql connection fetch time: 1.4588s
2013-01-15 03:06:31.132 GurbaniKhoj[1212:907] CoreData: annotation: total fetch execution time: 1.4607s for 92 rows.
EDIT 3: Is there any way I can make this faster? I still don't feel like 1.5 seconds is very fast though I'm doing these string comparisons for every single one.
Upvotes: 1
Views: 492
Reputation: 16664
Try to change fetch batch size from 1 to 20.
[request setFetchBatchSize:20];
Upvotes: 0
Reputation: 4339
Mukhi,
First, have you done the obvious thing and indexed your field?
Second, iOS devices have very slow fetch times. This isn't technically a flaw with Core Data. (Though CD may also be a performance sucking culprit here.) Hence, whenever possible, you should do large fetches into RAM and refine your search there. For example, when the first char is a 'b', fetch all of those and then refine from that subset in RAM with subsequent typed characters. You'll find that this is quite fast.
Third, the variability in performance you are seeing is probably due to the SQLite row cache and perhaps a filled MOC.
Andrew
Upvotes: 2