0

I'm asking mainly for Java, so that's what the examples here are in, but I'd expect this applies to other languages like C or C++ as well.


The first case is for common functions. Will it recognize that the code does a certain thing and replace it with something more optimal?

Easy examples:

int max(int a,int b){
    return a>b?a:b;
}

int rotateLeft(int a,int b){
    return (a<<b)|(a>>>-b);
}

boolean testBitLittleEndian(int v,int i){
    return (v>>i&1)!=0;
}

The rotate isn't so obvious, but to explain, the >>> is unsigned/logical shift, and shift amounts are interpreted modulo the width. Since ints are 32 bits, only the least significant 5 bits of the shift amount are used.

I think it's up to the JIT to replace this with the native rotate instruction.

Less obvious ones:

void intToByteLittleEndian(int v,byte[] b,int i){
    b[i+3]=(byte)(v>>24);
    b[i+2]=(byte)(v>>16);
    b[i+1]=(byte)(v>> 8);
    b[i  ]=(byte) v;
}

float median(float a,float b,float c){
    float d;//Swap
    if(a>b){d=a;a=b;b=d;}
    if(b>c){b=c;}
    return a>b?a:b;
}

Not even close to optimal, but it's straightforward and readable. Due to there being many variations of such functions it might be hard for the compiler to detect and optimize them properly.

Again, it might be up to the JIT to do the replacement since the instructions necessary for the optimized version are not available from Java.

Specifically for the write int as little endian function, to prevent the compiler from possibly thinking we may write part of the int and then get an out of bounds exception, we will write the last byte first.


The other case is standard library functions, which the compiler can know for sure is supposed to do something specific. There is no need to recognize and replace code, so even big functions like the math in BigInteger can be optimized if needed.

The Math class is one of the special ones specifically replaced with fast native instructions when possible.

There's also certain ones that are trivial in a low level language, such as Double.doubleToLongBits():

int64_t doubleToLongBits(double v){
    return *(int64_t*)&v;
}

Some more work if the endianness is wrong.

There are others with a pure Java implementation which will be optimized anyways.

It is also possible that only standard library functions are optimized in this way, because it's hard for the compiler to know exactly what your code does, or other reasons.


The main reason I've heard for compilers not being able to do such optimization is that they can't know exactly what you want, or in this case, what your code does. Beyond a certain complexity (which isn't very high) the compiler stops being able to analyze your code in a way that could let it make these optimizations.

  • You can always check the produced machine code / byte code. Of course you won't see what the JIT is doing. – Henry Oct 18 '17 at 04:01
  • Question is way too broad. The Java compiler generally doesn't optimize. What the JVM does depends entirely on the JVM in question. There is no single answer to your question. *Brand*, *Platform*, *Edition*, *Version*. Every combination may have a different answer. – Andreas Oct 18 '17 at 04:01
  • 3
    @Henry You can see the machine code generated by JIT: [How to see JIT-compiled code in JVM?](https://stackoverflow.com/q/1503479/5221149) – Andreas Oct 18 '17 at 04:03

1 Answers1

0

This is actually a bunch of questions. But...

javac optimizes nothing, it's not its job.

The JVM... there's no single JVM. There are many implementations and they usually optimize a lot at runtime. Let's speak about hotspot on amd64.

It recognizes some patterns and some methods, google for "JVM intrinsics".

For example, Math.max gets optimized using a conditional move, if the profiler says so (a rarely taken conditional branch is faster on the average).

Methods like Integer.rotateLeft, Long.rotateRight and many others get optimized to a single instruction. Your own code does not.

Bitwise operations are implemented efficiently.

The remainder of your question sounds more like an answer...

From this blog you can learn a lot about Hotspot optimizations.

maaartinus
  • 44,714
  • 32
  • 161
  • 320