Java experts emphasize the importance of avoiding premature optimization, and focusing instead on clean OO design. I am trying to reconcile this principle in the context of rewriting a program that uses a large array of long elements (a few million). It seems that using an ArrayList would consume about 3x the memory of a primitive array of longs, and wasting that much RAM seems like a legitimate concern to me.
I am basing this off an experiment I did using MemoryTestBench class described here. My test and output are as follows:
package memory;
import java.util.ArrayList;
import java.util.List;
public class ArrayListExperiment {
public static void main(String[] args) {
ObjectFactory arrayList = new ObjectFactory() {
public Object makeObject() {
List<Long> temp = new ArrayList<Long>(1000);
for (long i=0; i<1000; i++)
temp.add(i);
return temp;
}
};
ObjectFactory primitiveArray = new ObjectFactory() {
public Object makeObject() {
long[] temp = new long[1000];
for (int i=0; i<1000; i++)
temp[i] = i;
return temp;
}
};
MemoryTestBench memoryTester = new MemoryTestBench();
memoryTester.showMemoryUsage(primitiveArray);
memoryTester.showMemoryUsage(arrayList);
}
}
and output:
memory.ArrayListExperiment$2 produced [J which took 8016 bytes
memory.ArrayListExperiment$1 produced java.util.ArrayList which took 24968 bytes
My question is: How can I reap the benefits of an OO List and still retain the small memory footprint of a primitive array? I think guava might provide the answer, but glancing through the API it’s not obvious to me which class to use in place of ArrayList.
Thanks for any suggestions.
You might consider using Trove, which provides support for primitive collections, for example the
TDoubleArrayListclass:Edit: It’s true that this class doesn’t implement
List, but that’s Java’s price of avoiding boxed primitives. Guava’s solution is the most versatile, while Trove is best for more extreme performance requirements.