After reading the latest issue of I came across the section on parsing date strings, which gave me pause to look at some code I had been optimising recently.

I was using NSDateFormatter to parse date strings from a rails server and had thought nothing of it initially, but after running some tests it became clear I was wasting a lot of CPU cycles on this. Sam Soffes has written about similar results previously. For a quick test, fire up Code Runner and execute the block of code at the end of this README.

The gist of this code is that it generates an entire week worth of dates (one for every second) using strftime_l(3) first and then NSDateFormatter. It then parses them all using strptime_l(3) first and NSDateFormatter second, logging timings along the way. The results on my Mac this morning:

Creating 604800 date strings.
Created date strings using strftime_l(3) -- 1.42116 seconds
Created date strings using NSDateFormatter -- 1.74655 seconds
Parsing 604800 date strings.
Parsed date strings using strptime_l(3) -- 6.29914 seconds
Parsed date strings using NSDateFormatter -- 26.842 seconds

It's clear that NSDateNSString isn't hugely improved by using strftime_l(3), but strptime_l(3) is roughly 75% faster than NSDateFormatter for NSStringNSDate.

The project I was working on is already quite large, so I didn't want to end up diving into all the places I'm processing date strings and replace the simple dateFromString: call with all the mess that is involved with using strptime_l(3).

NSString *dateString = ...;

struct tm time;
strptime_l([dateString cStringUsingEncoding:NSASCIIStringEncoding], formatString, &time, NULL);
time_t timeInterval = mktime(&time);

NSDate *date = [NSDate dateWithTimeIntervalSince1970:timeInterval];

And that's where STRFTimeFormatter comes in. I wrote this to be a drop in replacement for NSDateFormatter1 that implements stringFromDate: and dateFromString:, so I could just replace the NSDateFormatter instances with instances of STRFTimeFormatter and I get the performance boost without the headaches.

As always: forks, comments, issues, pull-requests - all welcome.

  1. STRFTimeFormatter doesn't actually inherit from NSFormatter, so it isn't always API compatible.