views:

347

answers:

4

Hi,

Is the java compiler smart enough to optimize loop below (by extracting the

Double average = new Double( totalTime / callCount ); 

out of the for loop?

public double computeSD( Set values, int callCount, long totalTime ) {
  double diffs = 0.0d; 
  for( Iterator i=values.iterator(); i.hasNext(); ) {
    double value = ( ( Double )i.next() ).doubleValue(); 
    Double average = new Double( totalTime / callCount ); 
    diffs += ( value – average.doubleValue() ) * ( value – average.doubleValue() );
  } 
  double variance = diffs / callCount; return Math.sqrt( variance );
}
A: 

Not really. The compiler just writes out byte-code. If anything optimized the code, it'd be the Java Virtual machine and that probably depends on the platform, implementation and execution conditions...

Frank V
Are you sure that Java compilers don't do even obvious optimizations?
Mike Daniels
@Mike: The JIT compiler does. The source-to-bytecode compiler doesn't, but that's because it's not the place of the bytecode to be optimised, since it has to go through the JIT anyway.
Chris Jester-Young
@Matthew: Impedance mismatch alert---you and I are thinking of the JIT compiler, whereas I think Frank is only thinking of javac. The JIT compiler is where the heavyweight optimisations occur.
Chris Jester-Young
Yes, I misunderstood.
Matthew Flaschen
Ok. So the JIT will do the optimization. Based on the code above, how will it optimize the byte code on execution?
portoalet
The bytecode compiler really didn't perform a lot of obvious optimisations a while back, as I recall. When I was developing a 4k game for a competition (my hard disk crashed and I lost lots of progress -- argh!) I found out many interesting things which reduced the size of the source code significantly. For instance, trying to be clever with variables by placing them outside of the current iterative loop and reusing them often makes the code bigger. The 4k game applet is here if anyone wants to see: http://codeknight.net/t4k/ :)
Chris Dennett
+2  A: 

This may seem like an obvious optimization at first, but I don't think so, since it involves object instantiation. Granted, it's an instantiation of an immutable primitive box type, but that still doesn't guarantee that there's no side effect.

I don't think any current compiler can optimize this. For this to be optimized, the compiler must be told that some classes have special properties (which can be a dangerous proposition given that things may change in the future). That is, the compiler must be told specifics of the API. This can not be optimized at the language-level alone.

If you use double, however, it's much more likely to be optimized (e.g. using the loop-invariant code motion technique).

polygenelubricants
It's certainly possible for the JIT compiler to treat certain types, especially ones in `java.lang`, as magical. I'd be surprised if it didn't.
Chris Jester-Young
how would the primitive type be optimized?
portoalet
+2  A: 

If you really want to be sure, the answers to this question tell you how to see the native code that the JIT compiler produces.

Stephen C
+2  A: 

Nothing prevents the bytecode compiler (java->bytecode) from performing optimizations. When I worked at Symantec, and they did a Java IDE, the compiler write did look into putting some optimizations into our compiler but said nobody (in the outside world) seemed to be interested and the focus was on the Just In Time (JIT) compiler that is roughly the same as HotSpot in modern Sun VMs.

There is nothing that prevents a bytecode compiler from performing optimizations, but I am not aware of any that do so. There is huge focus on runtime optimizations, but those are pretty much hidden at runtime.

So, the source->bytecode compiler probably does not optimize it but the VM probably does. If you are on something like an Android then it probably performs no runtime optimization.

TofuBeer