So pretty much every question related to capacity in ArrayList is how to use it or (oddly) access it and I am quite familiar with that information. What I am interested in whether it is actually worth using the ArrayList constructor that sets capacity if you happen to know or have a rough idea how many items will be in the ArrayList?
Are there any comprehensive benchmarks comparing how long it takes to just use naive adding of elements to an ArrayList versus pre-setting the capacity of an ArrayList?
Obviously for any specific application you'd have to test any performance adjustments to determine if they are in fact optimizations (and if they are in fact necessary), but there are some times that setting the capacity explicitly can be worthwhile. For example:
I have nothing substantial to add to ruakh's answer, but here's a quick test function. I keep a scrap project around for writing little tests like these. Adjust the sourceSize to something representative of your data, and you can get a rough idea of the magnitude of the effect. As shown, I saw about a factor of 2 between them.
import java.util.ArrayList;
import java.util.Random;
public class ALTest {
public static long fill(ArrayList<Byte> al, byte[] source) {
long start = System.currentTimeMillis();
for (byte b : source) {
al.add(b);
}
return System.currentTimeMillis()-start;
}
public static void main(String[] args) {
int sourceSize = 1<<20; // 1 MB
int smallIter = 50;
int bigIter = 4;
Random r = new Random();
byte[] source = new byte[sourceSize];
for (int i = 0;i<bigIter;i++) {
r.nextBytes(source);
{
long time = 0;
for (int j = 0;j<smallIter;j++) {
ArrayList<Byte> al = new ArrayList<Byte>(sourceSize);
time += fill(al,source);
}
System.out.print("With: "+time+"ms\t");
}
{
long time = 0;
for (int j = 0;j<smallIter;j++) {
ArrayList<Byte> al = new ArrayList<Byte>();
time += fill(al,source);
}
System.out.print("Without: "+time+"ms\t");
}
{
long time = 0;
for (int j = 0;j<smallIter;j++) {
ArrayList<Byte> al = new ArrayList<Byte>();
time += fill(al,source);
}
System.out.print("Without: "+time+"ms\t");
}
{
long time = 0;
for (int j = 0;j<smallIter;j++) {
ArrayList<Byte> al = new ArrayList<Byte>(sourceSize);
time += fill(al,source);
}
System.out.print("With: "+time+"ms");
}
System.out.println();
}
}
}
Output:
With: 401ms Without: 799ms Without: 731ms With: 347ms
With: 358ms Without: 744ms Without: 749ms With: 342ms
With: 348ms Without: 719ms Without: 739ms With: 347ms
With: 339ms Without: 734ms Without: 774ms With: 358ms
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With