Thedwick

A Technologist Who Speaks Business

Thedwick

7 years ago
SimpleDateFormat: Performance Pig

Just yesterday I came across this problem “in the wild” for the third time in my career so far: an application with performance problems creating tons of java.text.SimpleDateFormat instances. So, I have to get this out there: creating a new instance of SimpleDateFormat is incredibly expensive and should be minimized. In the case that prompted this post, I was using JProfiler to profile this code that parses a CSV file and discovered that 50% of the time it took to suck in the file and make 55,000 objects out of it was spent solely in the constructor of SimpleDateFormat. It created and then threw away a new one every time it had to parse a date. Whew!

“Great,” you think, “I’ll just create one, static instance, slap it in a field in a DateUtils helper class and life will be good.”

Well, more precisely, life will be good about 97% of the time. A few days after you roll that code into production you’ll discover the second cool fact that’s good to know: SimpleDateFormat is not thread safe. Your code will work just fine most of the time and all of your regression tests will probably pass, but once your system gets under a production load you’ll see the occasional exception.

“Fine,” you think, “I’ll just slap a ‘synchronized’ around my use of that one, static instance.”

Ok, fine, you could do that and you’d be more or less ok, but the problem is that you’ve now taken a very common operation (date formatting and parsing) and crammed all of your otherwise-lovely, super-parallel application through a single pipe to get it done.

What would be better is to use a ThreadLocal variable so you can have your cake and eat it, too:

public class DateUtils {

    public static final String MY_STANDARD_DATE_FORMAT = "yyyyMMdd";

    public static java.util.Date parseDate(String dateString) throws ParseException {
        return getFormat().parse(dateString);
    }

    private static ThreadLocal format = new ThreadLocal(){
        protected synchronized Object initialValue() {
            return new java.text.SimpleDateFormat(MY_STANDARD_DATE_FORMAT);
        }
    }

    private static DateFormat getFormat(){
        return (DateFormat) format.get();
    }
}

I hope this code works because I wrote it on the fly and haven’t tried to run it, but you get the point.

♦ End

2 thoughts on “SimpleDateFormat: Performance Pig

  1. note that performance is bad because SimpleDateFormat has a calendar instance as a member and it is allocation of the calendar object that is expensive. This is also why it isn’t thread safe – if 2 threads change the calendar date or timezone or something at once the formats returned will be inconsistent.

UA-16297310-1

Run a SaaS app and want to know how to improve customer retention?

Sign up for our free 5-week email course on combating churn.