Tuesday, September 18, 2007

Java Performance Myths

I recently looked at the Jave Performance Myths presentation that Cliff Click gave at JavaOne. Some of the results were not surprising: final keyword does not help performance, autoboxing is nearly free. But other results were more interesting...

1. Try Catch Blocks are free - Ah, the smug feeling associated with quoting Joshua Block's Effective Java #39, Use Exceptions Only for Exceptional Conditions. This Effective Java entry says to use exceptions only when an exception has truly occurred. The rationale behind this is twofold: exception handling on JVMs is slow, and the code produced is obscure and confusing. It looks like the first reason is now longer true, but I'd still say that using exceptions to exit looks is poor code because it does not reveal intentions the way normal exiting of loops does.

2. Synchronization is cheaper than bugs - In Java Concurrency in Practice, Brian Goetz describes a proper synchronization policy as one that manages concurrent access to an object's state without violating any invariants or postconditions of that object. The speed at which critical sections can be entered and exited really shouldn't effect this policy. While I'm glad that the speed of synchronization has been increased, I don't see how this increase would effect software design. Originally, this myth seemed a lot more important than I think it is.

3. Garbage Collection Works, Use Object Pools sparingly - Garbage collection on lightweight and medium weight objects (think Hashtable) is now faster than if object pools and caching were used. Only under rare circumstances should we be using something like the flyweight pattern. This is what Neal Ford and Stuart Halloway have been saying for some time... many of the GoF design patterns are recipes for Java and C++ that don't have relevance in other languages. And now some of the patterns don't have relevance in Java.

4. Enum values() calls are expensive - The enum data type is Java 5 was supposed to be syntactic sugar and hold no performance implications. It looks like if-blocks and for-loops invoke enum.values() under the covers and this method holds a significant performance hit when called repeatedly. This can be avioded by moving calls to enum.values() out of the loop. Of course, profiling data should support this move before any decision to optimize is made (Effective Java 37 - Optimize Judiciously).

Check out the original Jave Performance Myths presentation for more info!

No comments: