My Web Log Book

Date parsing performance on iOS (NSDateFormatter vs sqlite)

Many web services choose to return dates in something other than a unix timestamp (unfortunately).

Recently I set out trying to identify performance bottlenecks with a large import operation in our iOS app. Having tweaked most of the variables, I was surprised to find out that date parsing was actually one of the biggest bottlenecks. The date parsing was done using NSDateFormatter using an ISO-8601 formatted date that looked like this:

2013-09-07T23:45:00Z

That looks simple enough. We had the NSDateFormatter’s format setup with a timezone of +0 GMT, and everything was great, expect parsing dates like this was consuming around 20% of the entire import operation. To provide some context, we were testing the import performance by importing roughly 250,000 objects into a SQLite database, and each object had 4 dates associated with it. That meant that we were dealing with a million dates, and parsing a million dates can get expensive.

Almost all of that time was being spent inside NSDateFormatter’s dateFromString: method, so there was not much we could do to optimize things ourselves.

The main goal was to get a unix timestamp from the ISO date. Luckily for us, SQLite is quite good at parsing some ISO-8601 dates and works blazingly fast. Here’s how SQLite can parse the above date:

sqlite> SELECT strftime("%s", "2013-09-07T23:45:00Z");
1378597500

Let’s convert this to use SQLite’s C library.

sqlite3_stmt *statement = NULL;
sqlite3_prepare_v2(db, "SELECT strftime('%s', ?);", -1, &statement, NULL);

sqlite3_bind_text(statement, 1, [dateString UTF8String], -1, SQLITE_STATIC);
sqlite3_step(statement);
sqlite3_int64 interval = sqlite3_column_int64(statement, 0);
NSDate *date = [NSDate dateWithTimeIntervalSince1970:interval];

Looks ugly, but we’re trying to solve a genuine problem here. So, how did this do in a performance run against NSDateFormatter? About 1400% faster. To parse a million randomly generated dates on an iPhone 5 running iOS 7, NSDateFormatter took a whooping 106.27 seconds, while the SQLite version took just 7.02 seconds.

Here’s a link to a gist containing the source code used for this comparison.

If you’re curious as to what SQLite is doing under the hood, checkout the date related code in SQLite at http://www.sqlite.org/src/doc/trunk/src/date.c. It mentions that the conversion algorithms it is using are from a book named Astronomical Algorithms by Jean Meeus.

  1. to-the-two reblogged this from vombat
  2. thought-palace reblogged this from vombat and added:
    vombat cleverly discovered that SQLite’s strftime function parses ISO-8601 (i.e. JSON) dates an order of magnitude...
  3. wisesabre reblogged this from vombat
  4. patoroco reblogged this from vombat and added:
    Interesting
  5. wowitsphil reblogged this from vombat
  6. dev-jac reblogged this from vombat and added:
    Interesting article that reflects the perks of knowing how to properly use SQLite.In tho case it is about converting...
  7. vombat posted this