Perché lo snippet di codice A 14x è più lento dello snippet di codice B?
(testato con jdk1.8.0_60 su Windows 7 64bit)Perché la finale statica è più lenta di una nuova su ciascuna iterazione
frammento di codice A:
import java.awt.geom.RoundRectangle2D;
public class Test {
private static final RoundRectangle2D.Double RECTANGLE = new RoundRectangle2D.Double(1, 2, 3, 4, 5, 6);
public static void main(String[] args) {
int result = RECTANGLE.hashCode();
long start = System.nanoTime();
for (int i = 0; i < 100_000_000; i++) {
result += RECTANGLE.hashCode(); // <= Only change is on this line
}
System.out.println((System.nanoTime() - start)/1_000_000);
System.out.println(result);
}
}
Codice frammento B:
import java.awt.geom.RoundRectangle2D;
public class Test {
private static final RoundRectangle2D.Double RECTANGLE = new RoundRectangle2D.Double(1, 2, 3, 4, 5, 6);
public static void main(String[] args) {
int result = RECTANGLE.hashCode();
long start = System.nanoTime();
for (int i = 0; i < 100_000_000; i++) {
result += new RoundRectangle2D.Double(1, 2, 3, 4, 5, 6).hashCode();
}
System.out.println((System.nanoTime() - start)/1_000_000);
System.out.println(result);
}
}
TL; DR: Utilizzando la La parola chiave new
all'interno di un ciclo è più veloce dell'accesso a un campo static final
.
(nota: rimozione della parola final
su RECTANGLE
non modifica il tempo di esecuzione)
Il test non tiene conto del tempo di avvio/avvio della JVM. I risultati saranno probabilmente incoerenti come scritti. Stai davvero testando la velocità di avvio della JVM, quindi esegui il tuo codice. – SnakeDoc
@SnakeDoc, riscaldamento/avvio JVM è certamente una considerazione, ma non spiega la differenza di prestazioni che vedo per i codici dell'OP. Anche dopo aver inserito un ciclo di riscaldamento in quello più lento, le prestazioni (migliorate) non si avvicinano a quelle più veloci. –
no, l'ho provato eseguendo il caso A, quindi il caso B all'interno di un'applicazione e quindi invertendo l'ordine, in entrambi i casi il caso A era 21x più lungo –