Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to improve Core Data performance?

My app has a UISearchBar allowing user to enter search keywords. Each keystroke executes a Core Data query in order to display the results as text in search bar changes.

The problem is that search bar keystrokes are lagging pretty bad... surely because of slow fetching. Any ideas how to improve the performance?

My Core Data is backed with sqlite data store which contains 1000 objects.

// searchKeyword is the string appears in UISearchBar
// Both title and author may contain several words so I can't use BEGINSWITH
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"(author CONTAINS[c] %@) OR (title CONTAINS[c] %@)", searchKeyword, searchKeyword];

NSEntityDescription* entity = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:managedObjectContext];

NSFetchRequest* request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
[request setPredicate:predicate];
[request setFetchLimit:10];

NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES];
NSArray* sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];

[sortDescriptor release];
[sortDescriptors release];

execute request and fetch the results
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                managedObjectContext:managedObjectContext
                                sectionNameKeyPath:nil
                                cacheName:nil];
NSError* error = nil;
BOOL success = [fetchedResultsController performFetch:&error];
[request release];
like image 687
Joshua Avatar asked Aug 15 '10 20:08

Joshua


People also ask

Is realm faster than Core Data?

Core Data is incredibly fast if you consider what it does under the hood to do its magic. But Realm is faster, much faster. Realm was built with performance in mind and that shows. As Marcus Zarra once said in a presentation, you don't choose Core Data for its speed.

What is your Core Data?

Core Data is a framework that you use to manage the model layer objects in your application. It provides generalized and automated solutions to common tasks associated with object life cycle and object graph management, including persistence.


1 Answers

Using CONTAINS slows it down. What you need to do is create a new table called searchWords (or whatever), and in that store all the words within your titles, made lower case and with accents removed. These have a relationship linking them back to the original objects. Make sure the word field is indexed.

Perform your query on this table, but instead of using CONTAINS or BEGINSWITH, do something like

word > "term" AND word < "tern"

Note that the first string in there is the search term, and the second is the search term with the last character incremented. This allows Core Data to use the SQL index to perform the search.

Apple have a Core Data WWDC session that explains this, including sample code. The sample code contains a class that handles normalising the string (I.e. Removing case), and incrementing the last character of a word in a unicode aware way.

like image 165
Amy Worrall Avatar answered Nov 15 '22 06:11

Amy Worrall