iPhone app memory related query - iphone

I am building an iPhone application .In the database I have 5000 records. Among them I am displaying only 50 in the app. But I want to ask would there be any memory issue if I create 5000 empty cells in the iPhone view initially even though I am displaying 50 rows of data?

If you build your table appropriately, you will only be using a handful to perhaps a dozen actual UITableViewCell objects which are constantly recycled as things show on screen.
Even 50 would be safe.
Having 5000 data objects in memory with 50 UITableViewCells should be pretty acceptable.
Especially if those data objects are small, or you are allowing CoreData to do some work for you with managing your data set.
The important thing is DO NOT MAKE 5000 TABLE CELL VIEWS. That is extremely poor practice.

iPhone has a limited amount of memory so you should always be careful to display only the data that is necessary for that view. You can implement infinite scrolling where when you reach the bottom of the screen through scrolling you trigger an event and load the next 25-50 records.
http://nsscreencast.com/episodes/8-automatic-uitableview-paging

One thing you'll quickly learn with the canonical way of handling tables is that regardless of the size of your model (i.e., the number of rows you intend to create), only a handful of rows are actually created, therefore the memory footprint remains low.
In essence, the UITableView initially creates and renders a screenful of rows (plus a few more for good measure). When you begin scrolling down, the controller recognises that it needs to draw a new row. But, it also realises that rows from the top of the table have disappeared from view. So, rather than create a whole new cell it simply takes one of the cells no longer in view and reconfigures it with the new info. No matter how many rows your table has, only those few cells live in memory.
So in your case, the memory bottleneck will likely be the model that is feeding the cell configuration. If you loaded all your 5000 rows into memory at once then that may be slow and memory consuming. But there is help at hand: you get a hint from the table controller that basically tells you that it wants to set up the *n*th row. So your model can in effect be more targeted and only load the data you need. E.g., since you know the 15th row is being rendered, then go and grab the 15th row from your database rather than preloading the entire model up-front.
This is the approach I've used to create apps with many more than 5000 rows without the need for paging. Of course it depends on your dataset as to how your user may navigate.

Related

Flutter app: fetch data from sqlite frequently or store in memory

I have a flutter app that has some master data and 2 bigger tables with parent child relation. The data is stored on the device in SQLite database. I expect hundreds or maybe a couple thousand records in the biggest table, which is the child table. From these records I create lists of objects.
In the app I need these lists ordered by different fields. For me it seems much easier to fetch the data from the database every time I need it.
My question is, which is the better approach?
Fetching the entire database when the app is opening and working with these lists in memory. For me the downside of this solution is that I need to maintain the order of the lists which can be quite painful compared to a single SQL statement. The order of the objects in those lists are quite important!
Or should I read the data from the database every time when I need it? And this means that I read only those records from the DB that I need for a given screen.
Which is the better approach from performance point of view?
Unless its forn an MVP with too little data then approach two.
It will be a little more cumbersome for you to implement but it will make the app more future proof and not waste loads of RAM(if the device does have enough).
You'll probably would have to implement paginated requests(selects, with limit and offset) While the user scrolls and reset those if the filters change.
Generally, paging is best choice for performance.
If you more optimize. Caching what has already been loaded, next page preload when scroll down

How to handle selection with large amounts of data in NatTable

When using the NatTable with a selection layer, if I have huge amounts (1million+) columns of data, selecting a row will take extremely long amounts of time (20 seconds+) or will outright crash my application. Is there a better way to handle selection of large amounts of data or maybe a way to select the entire amount but only visually show the amount of showing columns as selected and updating that as the table is scrolled?
It turns out that this is really a performance leak in NatTable. And interestingly it exists in that form for a long time and nobody has seen this until now.
I created a ticket [1] and work on a fix.
Until that you could try to remove or replace the "bad guys" from your composition. If that is not possible, you need to wait for the fix.
ColumnReorderLayer: if you don't need column reorder support, remove it from your layer stack (when talking about millions of columns, I suppose reordering is not a required feature)
ColumnHideShowLayer: if you don't need to support hiding columns, remove it from your layer stack. Not sure if you need it for your use case of showing millions of columns.
SelectionModel: I don't know your data model, but maybe the PreserveSelectionModel performs slightly better at the moment. Or have a look at the proposed fix attached to the ticket (once it is uploaded) and use a local version of that fix in your environment by creating a custom ISelectionModel implementation based on the fix.
[1] https://bugs.eclipse.org/bugs/show_bug.cgi?id=509685

Objective C UITableView 100 000 entries

I want to create a UITableView that dynamically searches and displays matching entries. My problem is that I do not know how to store these entries. I think a plain textfile or a property list is out of question, because with those types, the whole data is loaded at the beginning.
Does anyone have an alternative to these filetypes? I read about sqlite, but is this suitable for 100 000 entries? And is it possible to performantly search for entries? (I currently have the table in a text file. The entries are seperated by a certain string.)
Thanks in advance!
Core Data may be one API worth researching
http://developer.apple.com/library/ios/#documentation/DataManagement/Conceptual/iPhoneCoreData01/Introduction/Introduction.html
Core Data can be backed by several storage mechanisms, one being sqlite. Sqlite is probably your best bet for so much data.
Either SQLite or Core Data (which uses SQLite) would be appropriate and should be able to handle data sets of that size with little problem.
I think you'll find that UITableView will respond acceptably even when you have that many rows in the table. You'd never want the user to actually scroll through even 1000, let alone 100,000 rows, though, so make sure you give the user a filter to really cut down the number of rows before they have to look at the data.
Important: Make sure you use a fixed row height for your table cells. If you use a variable row height, UITableView will ask you for the height of every single row in the table just so it can figure out the total height of the table. The only way you'll get decent performance is to use a fixed height.

Does NSFetchedResultsController make a call to the DB every time the table view asks for a new row?

Does NSFetchedResultsController make a call to the DB every time the table view asks for a new row?
Did anyone track that? Apple says it makes sure that at any given time there is an minimum of needed objects in mem, so actually that could be the only way to do it. What's offscreen gets lost, and what's scrolling in is fetched immediately from the persistent store. Just like anyone else would do it in -tableView:cellForRowAtIndexPath: right? Or not?
NSFetchedResultsController and Core Data in general uses a fairly complex and highly optimized behind the scenes caching system. The caches are both in memory and on disk. It is certainly not a simple case of the fetched results controller making one disk access for each row of a table.
You can think of the fetched results controller as a data structure holding the data for the table. How it manages its relationship with the logical and physical data store really isn't relevant and in any case, it changes dynamically according to immediate conditions. If you design your data model properly, you end up optimized automatically.

Core Data - Large Datasets and Very Long Load Times

I've got about 5000-7000 objects in my core data store that I want to display in a table view. I'm using a fetched results controller and I haven't got any predicates on the fetch. Just a sort on an integer field. The object consists of a few ints and a few strings that hold about 10 to 50 chars in. My problem is that it's taking a good 10 seconds to load the view. Is this normal?
I believe that the FRC handles large datasets and handle's batches and such things to allow large datasets. Are there any common pitfalls or something like that because I'm really stumped. I've stripped my app down to a single table view, yet it still takes around 10 seconds to load. And I'm leaving the table view as the default style and just displaying a string in the cell.
Any advice would be greatly appreciated!
Did you check the index checkbox for the integer you are sorting on in your Core Data model?
On your fetch request, have you used -setFetchBatchSize: to minimize the number of items fetched at once (generally, the number of items onscreen, plus a few for a buffer)? Without that, you won't see as much of a performance benefit from using an NSFetchedResultsController for your table view.
You could also limit the properties being fetched by using -setPropertiesToFetch: on your fetch request. It might be best to limit your fetch to only those properties of your objects that will influence their display in the table view. The remainder can be lazy-loaded later when you need them.