NSDateFormatter performance

In this post I talk about NSDateFormatter and how to use it correctly in your applications, especially iPhone ones, because a misuse of it can cause serious performances issues.

NSDateFormatter instances are used to create string representations of NSDate objects or to convert NSDate objects to textual representation, so it’s very common to use it.

To illustrate this I’ll create a simple Navigation-based iPhone application, which has a UITableView. We will populate this tableView with 100 cells containing a formatted date based on a UNIX timestamp.
In the first test I’ll create a new NSDateFormatter for each cell. In the second I’ll put the NSDateFormatter as an ivar and initialize it once, and we will look at the difference of performance with Instruments.

1st method :

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

	UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
	if (!cell)
		cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

	NSDate* date = [NSDate date]; // get current date

	NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
	[formatter setDateFormat:@"dd/MM' - 'HH'h'mm"];
	cell.textLabel.text = [formatter stringFromDate:date];
	[formatter release];

	return cell;
}

2nd method :

-(void)viewDidLoad
{
  _formatter = [[NSDateFormatter alloc] init]; // _formatter is the NSDateFormatter ivar
  [_formatter setDateFormat:@"dd/MM' - 'HH'h'mm"];
}

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

	UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
	if (!cell)
		cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

	NSDate* date = [NSDate date]; // get current date

	cell.textLabel.text = [_formatter stringFromDate:date];

	return cell;
}

Now that we have our 2 examples, let’s compare with the Time Profiler Instrument.
In Xcode I chose Run with Performance Tool and select the Time Profiler template, by default this template isn’t available via Xcode, you have to launch Instruments, select it and then chose Save As Template.
The test is really simple, once the application launched, I scroll to the bottom of the tableView and go back to the top, then stop the test. To filter the quantity of information, check Hide Missing Symbols and Hide System Libraries. Now the line which interests us is the one containing the call to cellForRowAtIndexPath:
Now let’s compare the results with the 2 methods presented above.

1st :
NSDateFormatter performance showed in Instruments
2nd :
NSDateFormatter performance showed in Instruments
I don’t think there is much to say here, we clearly see that the first method is much much slower.

Why is that ? The explication is very simple, each time you create a NSDateFormatter the expression need to be compiled, and it takes time, lot of time.

So the conclusion is avoid to create formatters in loops or tableView delegate where you are supposed to hold lot of data because it’s a time killer. Just instantiate one formatter that you use the time your application live, and release it when you are done.

2 thoughts on “NSDateFormatter performance

  1. I was just seeking this info for a while. After 6 hours of continuous Googleing, finally I got it in your website. I wonder what’s the lack of Google strategy that don’t rank this kind of informative websites in top of the list. Normally the top sites are full of garbage.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>