Clear() vs list = new ArrayList < Integer >() ;

清除数组列表的两个选项中哪一个更好更快,为什么?

list.clear()

或者

list = new ArrayList<Integer>();

碰巧我必须随机清除数组列表中的所有条目我不知道将来会有多少新条目可能是0也可能是1000。哪种方法更快更好,为什么?

158631 次浏览

第一个 .clear();将保持相同的列表,只是清除列表。

第二个 new ArrayList<Integer>();在内存中创建一个新的 ArrayList

建议: 第一个,因为这就是设计的目的。

没有基准测试很难知道,但是如果你的数组列表中有很多条目,而且平均大小更小,那么创建一个新的数组列表可能会更快。

Http://www.docjar.com/html/api/java/util/arraylist.java.html

public void clear() {
modCount++;


// Let gc do its work
for (int i = 0; i < size; i++)
elementData[i] = null;


size = 0;
}

如果清除列表时很有可能包含与其包含的元素一样多的元素,并且您不需要空闲内存,那么清除列表是一个更好的选择。但我猜这可能并不重要。在检测到性能问题并确定其来源之前,不要尝试进行优化。

list.clear()将保持相同的 ArrayList,但是保持相同的内存分配。list = new ArrayList<int>();将为数组列表分配新的内存。

最大的区别在于数组列表将随着您需要更多的空间而动态扩展。因此,如果您调用 list.clear(),您仍然可能为 ArrayList 分配了大量可能不需要的内存。

也就是说,list.clear()会更快,但如果内存问题,你可能要分配一个新的数组列表。

我建议使用 list.clear ()而不是分配一个新对象。当您调用“ new”关键字时,您将在内存中创建更多的空间。实际上,这并不重要。我认为,如果您知道列表的大小,那么创建一个新空间,然后指定数组的大小可能是一个好主意。

事实是,如果你不做科学编程,这些都不重要。在这种情况下,你需要去学习 C + + 。

List.clear将在不降低列表容量的情况下删除元素。

groovy:000> mylist = [1,2,3,4,5,6,7,8,9,10,11,12]
===> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
groovy:000> mylist.elementData.length
===> 12
groovy:000> mylist.elementData
===> [Ljava.lang.Object;@19d6af
groovy:000> mylist.clear()
===> null
groovy:000> mylist.elementData.length
===> 12
groovy:000> mylist.elementData
===> [Ljava.lang.Object;@19d6af
groovy:000> mylist = new ArrayList();
===> []
groovy:000> mylist.elementData
===> [Ljava.lang.Object;@2bfdff
groovy:000> mylist.elementData.length
===> 10

在这里,mylist 被清除了,对它保存的元素的引用被取消了,但是它保持了相同的后台数组。然后 mylist 被重新初始化,得到了一个新的备份数组,旧的那个得到了 GCed。因此,一种方法保留内存,另一种方法抛出内存,从头开始重新分配(使用默认容量)。这取决于您是希望减少垃圾收集的波动,还是希望最小化当前未使用内存的数量。这个清单是否能够长时间地保存下来,从而被移出伊甸园,可能是决定哪个更快的一个因素(因为这可能会使垃圾收集更加昂贵)。

我认为答案是,这取决于一系列因素,例如:

  • 能否事先预测清单的大小(即你能否准确地设定清单的容量) ,
  • 列表大小是否可变(即每次填充时) ,
  • 在这两个版本中,列表的生命周期有多长,以及
  • 堆/GC 参数和 CPU。

这使得我们很难预测哪种情况会更好。但我的直觉告诉我,两者之间的差别不会太大。

关于优化有两点建议:

  • 不要 浪费时间试图优化这个... 除非应用程序是 客观地说太慢 还有测量使用剖析器 说明了一切你,这是一个性能热点。(其中一个先决条件很可能不成立。)

  • 如果你决定优化这一点,科学地去做。尝试(所有)这两种方法,并通过在实际问题/工作负载/输入集上测量实际应用程序的性能来决定哪种方法最好。(一个人为的基准可能会给你不能预测现实世界行为的答案,因为这些因素就像我之前列出的那些。)

尝试下面的程序,用两种方法。 1. 在 for 循环中清除数组列表 obj 2. 在 for 循环中创建新的数组列表。

List al= new ArrayList();
for(int i=0;i<100;i++)
{
//List al= new ArrayList();


for(int j=0;j<10;j++)
{
al.add(Integer.parseInt("" +j+i));
//System.out.println("Obj val " +al.get(j));
}
//System.out.println("Hashcode : " + al.hashCode());
al.clear();


}

令我惊讶的是,内存分配并没有太大的变化。

使用 New Arraylist 方法

循环前总可用内存: 64,909: :

循环后的总可用内存: 64,775: :

用清晰的方法,

循环前总可用内存: 64,909: : 循环后的总可用内存: 64,765: :

因此,从内存利用率的角度来看,使用 arraylist.clear 没有太大区别。