Tengo una situación donde el rendimiento es extremadamente importante. En el núcleo de mi algoritmo hay un método que hace algunos cálculos básicos con dos primitivas double
. Este método se llama más de diez millones de veces por ejecución del algoritmo.Java IEEE 64-bit 754 double, valores para evitar
El código se ve más o menos así;
public int compare(double xA, double xB, double yA, double yB);
double x = xA * xB;
double y = yA * yB;
double diff = x - y;
return (diff < 0.0 ? -1 : (diff > 0.0 ? 1 : 0));
}
Los parámetros xA
y yA
toman sus valores de un conjunto. Este conjunto se puede ajustar en el código. Veo diferencias de rendimiento enormes (aproximadamente el doble) según los valores que coloqué en el conjunto. Parece que si el conjunto contiene un 0.1
o un 0.3
, el rendimiento tiene un gran éxito. Mantener el conjunto a solo múltiplos de 0.5
le da el mejor rendimiento.
¿El compilador optimiza x * 0.5
como x >> 1
, etc.? ¿O es esto porque 0.1
no se puede definir en binario?
Me gustaría entender esta situación un poco mejor para que pueda optimizar esto. Supongo que podría ser un problema bastante difícil a menos que alguien sepa exactamente cómo javac y el jvm (en nuestro caso, el punto de acceso) maneja la multiplicación doble.
¿Seguro la diferencia de rendimiento es directamente en esta rutina y no una consecuencia del cambio de xA y Ya causar resultados diferentes para ser devueltos, cambiando así lo que se ejecuta después de esta rutina vuelve? –
Puede eliminar la resta borrando esa línea y reemplazando la declaración con 'return x y? 1: 0; '. –
Si el ajuste disponible se extiende hasta el punto en que los valores p y q para xA y yA pueden reemplazarse por p/q y 1, entonces se puede eliminar una multiplicación, dejando 'doble x = xA * xB; double y = yB; '(sujeto a los problemas habituales de redondeo de coma flotante). –