Java performance: exceptions

This was a real performance problems recently, with some details redacted.

It was found that filling in translated strings took up quite a lot of time. Translation requests are spread out all across the frontend, so no single step stood out, but with the help of YourKit, the problem was uncovered.

As it turns out, the main problem was with this construct:

for (int i = translationFiles.length - 1; i >= 0; i--) {
        try {
                ResourceBundle bundle = ResourceBundle.getBundle(translationFiles[i], locale, param);
                message = bundle.getString(messageKey);
        } catch (MissingResourceException e) {
                message = null;
        }
        if (message != null) {
                break;
        }
}

This could be idiomatic in Python, but it's not a great idea in very commonly used code in Java.

The reason is that exceptions are slow. Not too slow for exceptional cases, perhaps. But much too slow to do ten thousand times per page request.

There probably weren't many translationFiles when it was writted, but it has since increased to hundreds.

Rewriting it to not use exceptions reduced this step from roughly 30% of request time, to virtually nothing. For good measure, the result was also cached, to prevent the loop.

So whether or not you subscribe to the philosophy that "exceptions are for exceptional cases" in general, it's best to follow it in code that gets called a lot.

Note that it's the throwing that takes long (presumably due to stacktraces being created). It's fine to catch an exception in performance critical code, as long as it doesn't get thrown too often (only in exceptional cases).

 

Topics: #coding #java #performance

Comments

No comments yet

You need to be logged in to comment.