From the author of

From the author of

The VM Does What?

Most of the techniques I've shown here are things that people using low-level languages might tryafter all, they're the ones who tend to care about speedbut people using higher-level languages are not immune. A lot of received wisdom is based on old versions of a virtual machine; you may have been told to avoid some construct or use some feature because it was broken in an old version of a virtual machine, and this rule somehow gained the general consciousness as "Feature X is intrinsically slow."

One example is overuse of the final directive in Java, which can be used to indicate that a class should not be subclassed, or that a method can't be overridden. In very early Java virtual machines, final let the virtual machine do some clever optimizations, because it could eliminate the dynamic method lookup. In a modern Java virtual machine, however, the directive is only used by the code verification part; the optimizer ignores it entirely. Why? Because the VM already knows which classes aren't subclassed and which methods aren't overridden, and will apply these optimizations to all of them, not just the ones marked as final. If this practice becomes wrong in the future, as the result of loading some new classes, it will trigger recompilation of the affected classes. That's not to say that final should never be used, but it should be reserved for documentation, not for optimization.

Something similar is true with various bits of Erlang code, where certain code structures would trigger optimizations in older versions of the virtual machine, but now don't get any special treatment. If you want to make your code run quickly, give as much semantic information to your compiler and VM as possible. This design makes it easy for a future version of the compiler to identify your algorithm as a special case of something it knows how to optimize, and has the (highly beneficial) side effect of improving code readability and maintainability.

Most of the time, optimization isn't needed. Ruby, the byword in slow virtual machines, is used all over the place, with poorly written applications that use only a small fraction of a modern CPU. Don't optimize until you're sure that your code will be too slow without optimization; when you do need to optimize, make sure that your improvements actually help. A huge number of factors can affect performance, and not all of them are obvious. Make sure that you take all of the relevant factors into account.