0 votes
1 view
in Java by (4.1k points)

I was benchmarking some code, and I could not get it to run as fast as with java.math.BigInteger, even when using the exact same algorithm. So I copied java.math.BigInteger source into my own package and tried this:

//import java.math.BigInteger;

public class MultiplyTest {

    public static void main(String[] args) {

        Random r = new Random(1);

        long tm = 0, count = 0,result=0;

        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);

            long tm1 = System.nanoTime();

            BigInteger c = a.multiply(b);

            if (i > 100000) {

                tm += System.nanoTime() - tm1;

                count++;

            }

            result+=c.bitLength();

        }

        System.out.println((tm / count) + "nsec/mul");

        System.out.println(result); 

    }

}

When I run this (jdk 1.8.0_144-b01 on MacOS) it outputs:

12089nsec/mul

2559044166

When I run it with the import line uncommented:

4098nsec/mul

2559044166

It's almost three times as fast when using the JDK version of BigInteger versus my version, even if it's using the exact same code.

I've examined the bytecode with javap, and compared compiler output when running with options:

-Xbatch -XX:-TieredCompilation -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions 

-XX:+PrintInlining -XX:CICompilerCount=1

and both versions seem to generate the same code. So is hotspot using some precomputed optimizations that I can't use in my code? I always understood that they don't. What explains this difference?

1 Answer

0 votes
by (46.1k points)

Yes, HotSpot JVM is sort of "defrauding", because it has a specific version of some BigInteger ways that you won't find in Java code. These methods are declared JVM intrinsics.

In particular, BigInteger.multiplyToLen is an intrinsic way in HotSpot. There is a personal hand-coded assembly implementation in the JVM root base, but particularly for the x86-64 architecture.

You may impair this intrinsic with -XX:-UseMultiplyToLenIntrinsic option to violate JVM to use pure Java implementation. In this instance, the performance will be related to the appearance of your copied code.

Welcome to Intellipaat Community. Get your technical queries answered by top developers !


Categories

...