Ecco il mio codice di riferimento:
public void test(int copySize, int copyCount, int testRep) {
System.out.println("Copy size = " + copySize);
System.out.println("Copy count = " + copyCount);
System.out.println();
for (int i = testRep; i > 0; --i) {
copy(copySize, copyCount);
loop(copySize, copyCount);
}
System.out.println();
}
public void copy(int copySize, int copyCount) {
int[] src = newSrc(copySize + 1);
int[] dst = new int[copySize + 1];
long begin = System.nanoTime();
for (int count = copyCount; count > 0; --count) {
System.arraycopy(src, 1, dst, 0, copySize);
dst[copySize] = src[copySize] + 1;
System.arraycopy(dst, 0, src, 0, copySize);
src[copySize] = dst[copySize];
}
long end = System.nanoTime();
System.out.println("Arraycopy: " + (end - begin)/1e9 + " s");
}
public void loop(int copySize, int copyCount) {
int[] src = newSrc(copySize + 1);
int[] dst = new int[copySize + 1];
long begin = System.nanoTime();
for (int count = copyCount; count > 0; --count) {
for (int i = copySize - 1; i >= 0; --i) {
dst[i] = src[i + 1];
}
dst[copySize] = src[copySize] + 1;
for (int i = copySize - 1; i >= 0; --i) {
src[i] = dst[i];
}
src[copySize] = dst[copySize];
}
long end = System.nanoTime();
System.out.println("Man. loop: " + (end - begin)/1e9 + " s");
}
public int[] newSrc(int arraySize) {
int[] src = new int[arraySize];
for (int i = arraySize - 1; i >= 0; --i) {
src[i] = i;
}
return src;
}
Dalle mie prove, chiamando test()
con copyCount
= 10000000 (1E7) o superiore permette il warm-up da realizzare nel corso del primo copy/loop
chiamata, in modo da utilizzare testRep
= 5 è abbastanza; Con copyCount
= 1000000 (1e6) il riscaldamento necessita di almeno 2 o 3 iterazioni in modo da aumentare testRep
per ottenere risultati utilizzabili.
Con la mia configurazione (CPU Intel Core 2 Duo E8500 @ 3,16 GHz, Java SE 1.6.0_35-b10 ed Eclipse 3.7.2) risulta dal benchmark che:
- Quando
copySize
= 24, System.arraycopy()
e il ciclo manuale di prendere quasi lo stesso tempo (a volte uno è leggermente più veloce rispetto agli altri, altre volte è il contrario),
- Quando
copySize
< 24, il ciclo manuale è più veloce di System.arraycopy()
(leggermente più veloce con copySize
= 23, davvero veloce con copySize
< 5),
- Quando
copySize
> 24, System.arraycopy()
è più veloce del ciclo manuale (leggermente più veloce con copySize
= 25, il rapporto tempo di ciclo/tempo di copertura della matrice aumenta con l'aumentare di copySize
).
Nota: non sono madrelingua inglese, per favore scusate tutti gli errori di grammatica/vocabolario.
Hai provato e gestito un punto di riferimento? – corsiKa
Mi piacerebbe vedere un microbenchmark su questo. –
Penso che il codice nativo incorporato non sia influenzato dalle latenze JNI – gd1