几乎所有与ArrayList容量有关的问题都是如何使用它或(奇怪地)访问它,我对这些信息非常熟悉。我感兴趣的是它是否真的值得使用ArrayList构造函数来设置容量,如果你碰巧知道或者有一个大概的想法,ArrayList中有多少项目?为什么要使用ArrayList(int容量)?
是否有任何综合性的基准比较了如何使用天真添加元素到ArrayList与预先设置ArrayList的容量需要多长时间?
几乎所有与ArrayList容量有关的问题都是如何使用它或(奇怪地)访问它,我对这些信息非常熟悉。我感兴趣的是它是否真的值得使用ArrayList构造函数来设置容量,如果你碰巧知道或者有一个大概的想法,ArrayList中有多少项目?为什么要使用ArrayList(int容量)?
是否有任何综合性的基准比较了如何使用天真添加元素到ArrayList与预先设置ArrayList的容量需要多长时间?
很明显,对于任何特定的应用程序,您必须测试任何性能调整以确定它们是否实际上是优化的(并且实际上是否有必要),但有时候显式设置容量可能是值得的。例如:
这是一个很好的答案 – mfrankli 2012-03-20 04:10:11
ArrayList内部使用简单的数组来存储其元素,如果元素的数量超过了底层数组的容量,需要调整大小。因此,如果您知道List包含多少项目,您可以通知ArrayList使用所需大小的数组,因此不需要或执行调整大小逻辑。
我没有什么实质性的增加到ruakh的答案,但这里有一个快速测试功能。我写了一个废料项目来写这样的小测试。调整sourceSize以代表您的数据,并且可以大致了解效果的大小。如图所示,我看到他们之间的因素是2。
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();
}
}
}
输出:
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
当达到该ArrayList的容量,CLR创建一个与原始一个从原来的一个新创建的双重能力,并将所有元素的新的ArrayList一。因此,如果您有一些与所需大小有关的想法,则可以通过预先设置ArrayList的大小来保存这些额外的工作。 – 2012-03-20 03:53:56
@Deepansh:这不是Java问题吗? CLR是如何进入画面的?我想你的意思是JVM?此外,您的描述似乎正确,但“在CLR”(.Net)中,预先分配大小时需要更多时间。至少,这是在我测试1000000个项目时发生的情况。我测试了10-15次,每次默认的ArrayList构造函数都赢了! – TCM 2012-03-20 03:59:05
我说ArrayList,但它可以适用于概念,通常有一个由数组内部支持的集合的列表视图。 – Maverick 2012-03-20 04:02:06