Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it faster to create UITableViewCell programmatically or load one from a nib?

Time profiler shows the most time consuming operation in my app is loading UITableViewCells from nib files. The most expensive of which involves loading a UITableViewCell with a 4KB image.

I am loading the UITableViewCell from the nib with the following code:

    [[NSBundle mainBundle] loadNibNamed:@"UITableViewCellPortrait" owner:self options:NULL];
    cell = portraitCell;
    self.portraitCell = nil;

Has anyone compared the difference between creating a view programmatically or loading a UITableViewCell from a nib?

EDIT:
I compared the time profile of repeated runs of loading the UITableViewCell from a nib and creating the view programmatically. My test involved alternating between two UITableViews about 10 times in the span of 3-5 seconds. In each test, loading the UITableViewCell programmatically was substantially faster, between 2x to 6x faster.

Can anyone corroborate these results?

EDIT: I updated the nib loading code to only load the nib file once and use a cached version for subsequent calls.

    if (self.UITableViewPortaitNib == nil) {
        self.UITableViewPortaitNib = [UINib nibWithNibName:@"UITableViewCellPortrait" bundle:[NSBundle mainBundle]];
    }

    self.UITableViewPortaitNib instantiateWithOwner:self options:NULL];
    cell = portraitCell;
    self.portraitCell = nil;

I also used the automation instrument to create more consistent runs and the results still suggest loading UITableViewCells programmatically is faster than loading UITableViewCells for a nib. The average running time for loading UITableViewCells from a nib was around 90ms, while the average running time for creating the UITableViewCell programmatically was 50ms.

like image 345
Eytan Avatar asked Dec 13 '11 05:12

Eytan


3 Answers

Try creating a UINib object once and then sending it instantiateWithOwner:options: each time you need to create a new cell. From the UINib Class Reference:

For example, if your table view uses a nib file to instantiate table view cells, caching the nib in a UINib object can provide a significant performance improvement.

like image 100
rob mayoff Avatar answered Oct 18 '22 09:10

rob mayoff


In iOS 5 and mentioned in the WWDC 2011 videos, there is a newer method that uses UINib. You register your nib in your viewDidLoad: method and then simplify the code in the tableView:cellForRowAtIndexPath: method. This may speed things up for you (but I've never performed any comparison timings).

Example: In your viewDidLoad: register the nib and retain a reference to it:

NSString *myIdentifier = @"ReusableCustomCell";
[self.reuseCustomCell registerNib:[UINib nibWithNibName:@"ReusableCustomCell" bundle:nil] forCellReuseIdentifier:myIdentifier];

In your tableView:cellForRowAtIndexPath: method just ask for the cell (no need to check for nil as it is guaranteed to return a cell under iOS5) and configure the cell:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *myIdentifier = @"ReusableCustomCell";

    ReusableCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:myIdentifier];
    // Your configuration code goes here
    cell.nameLabel.text = @"some text";
    // ....

    return cell;
}

Code not tested. I'd be interested if this was any faster than using UINib alone.

like image 43
Robotic Cat Avatar answered Oct 18 '22 10:10

Robotic Cat


I load the nib cell (cellTemplate) once and duplicate it as needed, so in a sense this approach is both programmatic and nib based.

Duplicating was more complicated than I expected as mutableCopy didn't work. An NSKeyedArchiver roundtrip did, however:

NSData* cellData = [NSKeyedArchiver archivedDataWithRootObject:cellTemplate];
cell = [NSKeyedUnarchiver unarchiveObjectWithData:cellData];

In fact if you're going for raw, blazing, pedal-to-the-metal speed, even the archived template can be calculated once and cached.

But shouldn't you be measuring frame rate? In that case the UIView's complexity comes into play too.

like image 2
Rhythmic Fistman Avatar answered Oct 18 '22 09:10

Rhythmic Fistman