Tuesday, September 10, 2013

Date Parsing Performance: NSDateFormatter vs. SQLite

Jens Alfke:

vombat cleverly discovered that SQLite’s strftime function parses ISO-8601 (i.e. JSON) dates an order of magnitude faster than NSDateFormatter does, even with the overhead of having to generate and evaluate a SQL SELECT statement to run it.

I decided to go one step farther — I tweezed out the ~250 lines of C code from SQLite that implement the actual parsing, and got them to build independently. This adds another factor of 2x speed.

I enjoy reading the SQLite code. NSDateFormatter also seems to be responsible for Numbers’ horrific performance when opening CSV files.

5 Comments RSS · Twitter

Also, don't instantiate a lot of NSDateFormatter. It's slow. Instead what I do is I wrap each of the date format I'm using into a global C function where I initialize a date formatter on the first call, adjust it to match the format for this function and put it into a static variable inside the function. Way faster. In my case I was converting a lot of dates to strings, not parsing them, but this class is slow in more than one way.

I wonder if slow instantiation is related to the creation of new NSCalendar instances: http://www.mikeabdullah.net/NSCalendar_currentCalendar.html

NSDateFormatter performance might be bad also because of taking into account all kind of possible localization issues? And the fact that these can change while the app is running. While changing locale when the app is running is an edge case, it's not the responsibility of the framework to optimize that (?).

@michel I hope you also use dispatch_once in your function ;-)

@charles Makes sense about NSCalendar. I don't remember which internal functions took all that time, it's been a few months since I profiled that.

I'm not using dispatch_once because it's pointless as I'm only using these functions from the main thread. NSDateFormatter isn't thread-safe anyway (or is it?), so a correct thread-safe implementation would need to use thread-local instances, and dispatch_once won't work with that.

It definitely helps if you can avoid instantiating lots of NSDateFormatters. I generally keep one per thread (per format). From what I’ve seen, NSCalendar was not the cause of the instantiation slowness. I would not expect changing localization circumstances to affect the formatter after it has been created and configured (unless you are using +autoupdatingCurrentCalendar). But I suppose you’re right in that being more general-purpose may make it slower.

[…] you’re parsing ISO-8601(JSON) dates, try Date Parsing Performance: NSDateFormatter vs. SQLite […]

Leave a Comment