¿Hace trampa Java JIT al ejecutar código JDK?


Yo estaba benchmarking algo de código, y yo no podía llegar a correr tan rápido como con java.math.BigInteger, incluso cuando se utiliza el mismo algoritmo. Así que copié java.math.BigInteger fuente en mi propio paquete y probado esto:

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

Cuando corro esto (jdk 1.8.0_144-b01 en macOS) sale:

12089nsec/mul
2559044166

Cuando lo corro con la línea import uncomented:

4098nsec/mul
2559044166

Es casi tres veces más rápido cuando se utiliza la versión JDK de BigInteger frente a mi versión, incluso si está utilizando el exacto el mismo código.

He examinado el bytecode con javap, y comparado la salida del compilador cuando se ejecuta con opciones:

-Xbatch -XX:-TieredCompilation -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions 
-XX:+PrintInlining -XX:CICompilerCount=1

Y ambas versiones parecen generar el mismo código. Entonces, ¿hotspot está usando algunas optimizaciones precalculadas que no puedo usar en mi código? Siempre entendí que no lo hacen. ¿Qué explica esta diferencia?


Warning: Undefined property: agent_blog_content::$date_asked in /var/www/agent_etc/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 32

Warning: Undefined property: agent_blog_content::$count_answers in /var/www/agent_etc/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 52