Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array filter vs. Core Data pull performance

I'm wondering about the performance differences between two different methods of data filtering. Here's what I'm working with:

  • A set of core data objects
  • A UISegmentedControl that represents a boolean filter (learned vs. not learned)
  • A UITableView that displays the filtered data set

As I see it, there are two possible approaches here:

  1. Pull the entire core data set in viewDidLoad. Filter the array of data using a predicate when the segmented control value changes. Reload the tableview.
  2. Initially pull the core data set with a predicate. When the segmented control value changes, re-pull the core data set with the updated predicate. Reload the tableview.

I know there are factors that influence the answer (how large the data set is, how often the segmented control will be used), I'm just wondering if there is an overall best practice between the two.

like image 457
Whoa Avatar asked Nov 29 '13 01:11

Whoa


2 Answers

There are trade-offs between the two approaches, and the best choice depends on how important the differences are to you. No one approach is the best practice for every situation.

Loading everything up front in one array will likely have:

  • Slower startup time (because of doing a large fetch right off)
  • Higher memory use (since you're fetching everything rather than just a subset)
  • Faster when switching between filter options (since you already have the data)

Doing a new fetch every time will likely have:

  • Faster startup time
  • Lower memory use (since you only ever have a subset of the total collection)
  • Slower when switching between filter options, at least at first (Core Data's internal row cache will speed things up on subsequent switches).

How significant the factors are depends on your data and your app. If you have lots of data, then the memory use may be significant (fetching every instance of an entity type is an easy way to blow out your memory use). Speed concerns depend on what else your app is doing at the same time and, frankly, on whether either option is slow enough to cause a noticeable delay. If your data set is small, it probably doesn't make much difference which approach you use.

like image 106
Tom Harrington Avatar answered Nov 11 '22 18:11

Tom Harrington


I don't expect there will be any user-noticeable speed difference.

Therefore these are best practices that I think are relevant here:

  1. Avoid premature optimization.
  2. You're constrained by memory more often than speed.
  3. Design in advance.

From this I deduce three points of advice that apply to current problem:

  1. Go with the method that is easiest to maintain.
  2. Don't pull more objects from Core Data than necessary.
  3. Have some strategy about updating the data in the tableview.

To combine those points in one advice, it's best to use the class NSFetchedResultsController for displaying Core Data in tables as it's specifically designed for this purpose:

  1. Encapsulates the idea of "the chunk of data I'm currently displaying".
  2. Saves you memory by not pulling things you don't need.
  3. Helps with updating data in tableview.

You can play with examples of it by creating a new Core Data-based project in Xcode (4.4 or later). It's closer to the second of your approaches.

like image 3
ilya n. Avatar answered Nov 11 '22 18:11

ilya n.