One of the many mantras that is drilled into iOS devs is that you shouldn’t recreate expensive, complex objects like formatters every time you need them. Instead, keep them around in a static or instance variable and use them as needed. To test this, I created a playground and put this file in the Sources folder:
[gist https://gist.github.com/JoshuaSullivan/6c0d0134e66c60c6cd8c file=”FormatterTest.swift”]
I didn’t put the code directly into the playground because doing ANYTHING in a playground 100k times is going to take a very long time and not be very representative of real-world conditions.
Here’s the playground code, which simply invokes the tests and records the results:
[gist https://gist.github.com/JoshuaSullivan/6c0d0134e66c60c6cd8c file=”Playground.swift”]
The results were unequivocal: creating an NSDateFormatter each time you need to use it is roughly 9x slower than creating it once and using it repeatedly. That said, this is only likely to be an issue for tasks where there is a lot of date formatting going on, such as in a table view with dates in every cell. If you have a situation where you only need to format a single date infrequently (today’s date in a page header, for example), then you shouldn’t worry about hanging on to the date formatter; even though it’s heavy, it only takes a tiny fraction of a second to instantiate one.
CONVENTIONAL WISDOM: CONFIRMED
Addendum: At the request of a coworker (@rexeisen), I added in a test of the static NSDateFormatter.
test. As you can see, the results are no better than creating an instance each time. That said, it would be more convenient to use for 1-off formatting tasks, where keeping the formatter around is unnecessary.
localizedStringFromDate(_:dateStyle:timeStyle:)
Addendum II (2016-01-15): Further testing has revealed that changing the timeStyle and dateStyle of an NSDateFormatter
is tremendously expensive. Even more so than just creating a new formatter for each use! Across several trials, performance using a single NSDateFormatter
that is re-parameterized on each use was 10% slower than creating a new formatter each time and a full 10x slower than using a single, pre-configured formatter. The take away here is, create a formatter for each repeating case, don’t try to make a single shared formatter do all the work.