幾乎所有與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