HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Ugly optimized caching of SimpleDateFormat

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
cachinguglysimpledateformatoptimized

Problem

Concerning the optimization of this simple function

String formatDate(String format, Locale locale, Date date) {...}


formatting a Date using a SimpleDateFormat created with the arguments format and locale. I'm curious what you thing about the code below. I know it's terrible, but let's assume two things

  • The code must be as fast as possible.



  • There's no suitable object to hold the cache.



  • It must not cause any memory leaks.



Because of 1., a thread local cache should be used. However, the passed format and arguments may differ from those used in the cache and this must be checked. Funnily, although SimpleDateFormat is mutable (which is the cause of all problems), there seem to be no way how to change its format or locale. Actually, the parameters hardly ever change, but there's no guarantee.

Because of 2., the cache must be a static field.

Because of 3., no ThreadLocal.initialValue can be used as it'd lead to memory leaks just like in this question. For the same reason no custom class may be put into the ThreadLocal.

This all is pretty restrictive. So I wrote the following ugliness

private String toString(Date obj, String format, Locale locale) {
    return getSimpleDateFormat(format, locale).format(obj);
}

private SimpleDateFormat getSimpleDateFormat(String format, Locale locale) {
    Object[] list = SDF.get();
    // An identity check is faster and correct as missing an entry is allowed.
    // It's surely good enough as passing equals but not same parameters hardly ever happens.
    if (list!=null && list[0] == format && list[1] == locale) {
        return (SimpleDateFormat) list[2];
    }
    final SimpleDateFormat result = new SimpleDateFormat(format, locale);
    list = new Object[] {format, locale, result};
    SDF.set(list);
    return result;
}

/** Contains triples (String format, Locale locale, SimpleDateFormat sdf) */
private static final ThreadLocal SDF = new ThreadLocal();


I don't care about naming and

Solution

What about using a WeakHashMap? The memory leak is not really an issue since the memory can be reclaimed at any time.

Also, if I were using a map, I would define a FormatAndLocale util class, with valid hashCode and equals, to be used as keys.

Context

StackExchange Code Review Q#62208, answer score: 3

Revisions (0)

No revisions yet.