/**
* Since we will be using the large array, or List, to be doing millions of lookups, we want to
* test if doing lookups on a List<Long> is slower than doing the exact same lookups on a
* long[]. Unfortunately, it is.
*
* Sample output showing 2x speed decrease in memory lookups from gauva wrapped
* long[] vs a naked primitive long[]. Trove performance, on the other hand, is still
* very fast, presumably because it avoids boxing/unboxing:
*
* 8607317423706504585
* 154.0
* 8607317423706504585
* 337.0
* 8607317423706504585
* 156.0
*/
package memory;
import java.security.SecureRandom;
import java.util.List;
import gnu.trove.list.array.TLongArrayList;
import com.google.common.primitives.Longs;
public class MemoryAccessTest {
public static final int NUM_LOOKUPS = 10000000; // number of lookups we'll do
public static final int ARR_LENGTH = 3000000; // length of array (or List) we'll be performing the lookups on
// a large sample of random lookup indices.
public static int[] lookupIndices = new int[NUM_LOOKUPS];
// a random number generator
public static SecureRandom rng;
static {
rng = new SecureRandom();
for (int i=0; i<NUM_LOOKUPS; i++) {
lookupIndices[i] = rng.nextInt(ARR_LENGTH);
}
}
public static void main(String[] args) {
SecureRandom rng = new SecureRandom();
long[] primitive = new long[ARR_LENGTH];
for (int i=0; i<ARR_LENGTH; i++) {
primitive[i] = rng.nextLong();
}
List<Long> guava = Longs.asList(primitive);
TLongArrayList trove = new TLongArrayList(primitive);
// Time the primitive version
double startPrimitive = System.currentTimeMillis();
// a dummy variable for tracking the lookups, just to make
// sure Hotspot doesn't optimize anything away.
long sum = 0;
for (int i=0; i<NUM_LOOKUPS; i++) {
sum += primitive[lookupIndices[i]];
}
double endPrimitive = System.currentTimeMillis();
System.out.println(sum);
System.out.println(endPrimitive - startPrimitive);
// Time the guava version
double startGuava = System.currentTimeMillis();
sum = 0;
for (int i=0; i<NUM_LOOKUPS; i++) {
sum += guava.get(lookupIndices[i]);
}
double endGuava = System.currentTimeMillis();
System.out.println(sum); // sanity check: make sure the two sums match
System.out.println(endGuava - startGuava);
// Time the trove version
double startTrove = System.currentTimeMillis();
sum = 0;
for (int i=0; i<NUM_LOOKUPS; i++) {
sum += trove.get(lookupIndices[i]);
}
double endTrove = System.currentTimeMillis();
System.out.println(sum); // sanity check: make sure the two sums match
System.out.println(endTrove - startTrove);
}
}