Estaba comparando un código y no pude ejecutarlo tan rápido como con java.math.BigInteger
el mismo algoritmo. Así que copié la java.math.BigInteger
fuente en mi propio paquete y probé 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 ejecuto esto (jdk 1.8.0_144-b01 en MacOS) sale:
12089nsec/mul
2559044166
Cuando lo ejecuto con la línea de importación sin comentarios:
4098nsec/mul
2559044166
Es casi tres veces más rápido cuando se usa la versión JDK de BigInteger en comparación con mi versión, incluso si se usa exactamente 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, ¿el punto de acceso utiliza algunas optimizaciones precalculadas que no puedo usar en mi código? Siempre entendí que no. ¿Qué explica esta diferencia?