Does Java JIT cheat when running JDK code?
Yes, HotSpot JVM is kind of "cheating", because it has a special version of some BigInteger
methods that you won't find in Java code. These methods are called JVM intrinsics.
In particular, BigInteger.multiplyToLen
is an instrinsic method in HotSpot. There is a special hand-coded assembly implementation in JVM source base, but only for x86-64 architecture.
You may disable this instrinsic with -XX:-UseMultiplyToLenIntrinsic
option to force JVM to use pure Java implementation. In this case the performance will be similar to the performance of your copied code.
P.S. Here is a list of other HotSpot intrinsic methods.
In Java 8 this is indeed an intrinsic method; a slightly modified version of the method:
private static BigInteger test() { Random r = new Random(1); BigInteger c = null; for (int i = 0; i < 400000; i++) { int s1 = 400, s2 = 400; BigInteger a = new BigInteger(s1 * 8, r), b = new BigInteger(s2 * 8, r); c = a.multiply(b); } return c;}
Running this with:
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining -XX:+PrintIntrinsics -XX:CICompilerCount=2 -XX:+PrintCompilation <YourClassName>
This will print lots of lines and one of them will be:
java.math.BigInteger::multiplyToLen (216 bytes) (intrinsic)
In Java 9 on the other hand that method seems to not be an intrinsic anymore, but in turn it calls a method that is an intrinsic:
@HotSpotIntrinsicCandidate private static int[] implMultiplyToLen
So running the same code under Java 9 (with the same parameters) will reveal:
java.math.BigInteger::implMultiplyToLen (216 bytes) (intrinsic)
Underneath it's the same code for the method - just a slightly different naming.