Ho una situazione in cui le prestazioni sono estremamente importanti. Al centro del mio algoritmo c'è un metodo che fa alcuni calcoli di base con due primitive double
. Questo metodo è chiamato oltre dieci milioni di volte per esecuzione dell'algoritmo.Java IEEE 64-bit 754 double, valori da evitare
Il codice è simile a questo;
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));
}
I parametri xA
e yA
assumono valori da un set. Questo set può essere ottimizzato nel codice. Sto vedendo differenze di prestazioni enormi (circa il doppio) a seconda dei valori che ho inserito nel set. Sembra che se il set contiene uno 0.1
o uno 0.3
, le prestazioni hanno un grande successo. Mantenere il set a soli multipli di 0.5
offre le migliori prestazioni.
Il compilatore sta ottimizzando x * 0.5
come x >> 1
ecc.? Oppure perché 0.1
non può essere definito in binario?
Mi piacerebbe capire questa situazione un po 'meglio in modo da poter ottimizzare questo. Immagino che potrebbe essere un problema piuttosto difficile a meno che qualcuno non sappia esattamente come javac e jvm (nel nostro caso hotspot) gestiscono la doppia moltiplicazione.
Sei sicuro la differenza di prestazioni è direttamente di questa routine e non una conseguenza del cambiamento xA e yA causando risultati diversi da restituire, modificando in tal modo ciò che viene eseguito dopo questa routine ritorna? –
È possibile eliminare la sottrazione eliminando quella riga e sostituendo la restituzione con 'return x y? 1: 0; '. –
Se il tweaking disponibile si estende al punto in cui i valori p e q per xA e yA possono essere sostituiti da p/q e 1, allora una moltiplicazione può essere eliminata, lasciando 'double x = xA * xB; double y = yB; '(soggetto ai soliti problemi di arrotondamento a virgola mobile). –