Just getting caught up on email...
Not to be argumentative, but optimizing compilers are pretty old
technology, Walden
Absolutely agreed. But there are certain optimizations that a complier
cannot do, and must be left to the runtime. There again, though, JIT
optimizers are nothing new. I'm referring to specific optimizations that
the CLR JIT can do (and perhaps the JVM does too, I honestly don't
know.) but they're impressive nonetheless.
One example of this is dropping inaccessible code, when the
accessibility of the code is determined at runtime (something an
optimizing _compiler_ cannot do). We have logging throughout our
application, in our case calls to log4net, which is the .net version of
log4j. In some of our core objects we have functions that get called
once for each field of each row loaded from the database, IOW, they're
call a lot! In a typical day these are functions that are called
literally millions of times, if not tens to hundreds of millions of
times. Squeezing every last drop of performance out of these functions
is critical, but we don't want to sacrifice readability, maintainability
or debugability.
We originally had simply calls like log.debug("some data"); throughout
our code. Of course the first thing the debug() function does is check
the debug flag and bail if it's not set, but it still a function call.
And more importantly, if getting the values to be passed to the function
is "expensive" it's an expense not needed. Next step, wrap the calls to
log.debug() in an if statement that checks the debug flag ourselves.
This lets us avoid the expense of gathering information that will not be
needed, and this is an improvement. But we still have all the code in
the cpu-cache, and we're still doing a compare. So, last step, make the
debug flag static readonly. What's the difference? Well, when the JIT
compiler kicks in to x-late the .net CIL (eg. Java byte-code) to the
actual executing machine instructions the jit compiler sees that the
flag is set to false, and it's static readonly, so it can't ever be
true, and it will drop the entire if and its contents on the floor and
generate the machine instructions as if the if was never there in the
first place. Result is smaller tighter faster runtime code.
A second example would be the ability to emit CIL at runtime. Reflection
is great, but it's slow. Again, in functions that are called often it's
important to be able to generate code at runtime to optimize
performance. I would imagine I can do this is Java too, but I'd like to
know the details.
A final example would be garbage cleanup. And yes, the JVM has GC too.
And this is what I was really asking for.. can we have a comparison
(non-religious one) of the good, bad and ugly of the two VMs? I know the
CLR, but I don't know he JVM. I'd like to be informed about the details
of both.
I'll be the first to admit, these are things that the average
_application_ developer shouldn't know or care about! I've used the CLR
for years, but it wasn't until we started working with our own ORM
tooling that we needed to dig into it at such a low level.
-Walden
As an Amazon Associate we earn from qualifying purchases.