Filter huge NSArray
ios, nsarray, nspredicate
Solution
`NSPredicate` focuses on flexibility rather than speed. For an in-memory `NSArray` (i.e. not a Core Data relationship), you can generally get much better performance by just using a loop.
If it is still too slow, then there are several approaches:
Coalesce your requests. See Is there a simple way (in Cocoa/iOS) to queue a method call to run once in the next run loop? You can create a coalescing trampoline so that you only will update your list every few hundred milliseconds. That way if the user types very quickly, you don't re-filter the list every single chaacter.
Be smarter about filtering. If you just filtered for "bo" and you now want to filter for "bob", you know it's a subset of that previous list. You don't have to re-filter everything. Writing a good algorithm for this takes a little work but can dramatically improve performance.
Perform your filtering on an `NSOperationQueue` (easier to cancel than GCD, but GCD also works), and let the UI use KVO to notice when the filtered array changes.
Keep track of the actual changes (adds/deletes) while filtering. You shouldn't call `reloadData` on your table view if you can help it. You should perform inserts and deletes (`insertRowsAtIndexPaths:`). That avoids constantly churning your cells, and it also generally looks better. Again, the code is more complicated, but the improvements can be dramatic.
Problem
I'm filtering an NSArray with a NSPredicate and using the filtered array for my UITableView. I'm using this filtering when the user inputs text in a UITextField. So every time the text in the UITextField changes I'm calling my filter function. It looks like this: ``` NSArray *hugeArray = ...; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", input]; _resultArray = [hugeArray filteredArrayUsingPredicate:predicate]; [_myTableView reloadData]; ``` When I'm using a NSArray with a lot of objects the input becomes very slow (the complete input in the UI becomes slow). Is there any possibility to get a better performance or run the filtered command in background? Writing something in the UITextField shouldn't be blocked. When the UITableView will be refreshed after a very short time after the input it may be ok.