【发布时间】:2018-02-28 18:05:49
【问题描述】:
哪些在 java 中运行得更快? 假设我想多次使用一个 ArrayList 但具有不同的值,那么是使用 clear() 方法还是将 arraylist 设置为 null 更好??
【问题讨论】:
标签: java performance arraylist
哪些在 java 中运行得更快? 假设我想多次使用一个 ArrayList 但具有不同的值,那么是使用 clear() 方法还是将 arraylist 设置为 null 更好??
【问题讨论】:
标签: java performance arraylist
1) 其实你要比较的不是
temp=null; versus temp.clear();
但是
temp=new ArrayList<>(); versus temp.clear();
或者换一种说法:我们应该创建一个新的ArrayList 还是通过调用clear() 回收旧的?
看看这段代码没有回收旧的ArrayList实例:
for(int i=0;i<2000;i++)
{
temp=new ArrayList<Integer>();
for(int j=0;j<2000;j++)
{
temp.add(j);
}
ret.add((ArrayList<Integer>)temp.clone());
temp=null;
}
temp=null 是外部for 语句的最后一条语句,在此for 的每次迭代开始时,先前由temp 变量引用的ArrayList 对象被丢弃为新的@987654332 @ 已创建并分配给。
所以把它分配给null 太没用了。
2) 您的测试存在偏差。
回收ArrayList 实例可以提供更好的结果,因为您有适合的用例。
ArrayList 被备份到一个数组。
在外循环的第一次迭代中,内循环的迭代使后备数组增长了多次。
因此,在外循环的下一次迭代中,它利用了支持的数组具有目标大小。
因此不需要增加后备数组。
例如,如果您更改代码版本,在每次迭代中重新创建 ArrayList 的新实例以调用构造函数 public ArrayList(int initialCapacity),并以 2000 作为参数,它应该会改进实际最慢的版本。
【讨论】:
ArrayList 会迭代 2 000 个元素 2 000 次。这很重要。所以通过指定 ArrayList 的目标大小并避免迭代清除,这个版本可能只会更快。
clear() 实现迭代所有元素以将它们设置为 null :for (int i = 0; i < size; i++) elementData[i] = null;
所以要知道这一点,我使用不同的方法运行此代码两次以清除数组。 首先我使用了 clear 方法
`class Check
{
public static void main (String[] args) throws java.lang.Exception
{
ArrayList<ArrayList<Integer>> ret=new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> temp=new ArrayList<Integer>(2000);
for(int i=0;i<2000;i++)
{
for(int j=0;j<2000;j++)
{
temp.add(j);
}
ret.add((ArrayList<Integer>)temp.clone());
temp.clear();
}
}
}
`
我得到了以下统计数据: 运行时间:1.87s 内存:4386816KB
另一方面,当我使用以下代码使用 null 方法运行时。
` class Check
{
public static void main (String[] args) throws java.lang.Exception
{
ArrayList<ArrayList<Integer>> ret=new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> temp;
for(int i=0;i<2000;i++)
{
temp=new ArrayList<Integer>(2000);
for(int j=0;j<2000;j++)
{
temp.add(j);
}
ret.add((ArrayList<Integer>)temp.clone());
}
}
}
` 我得到的统计数据为 运行时间:0.19s 内存:4386816KB
所以很明显 "clear()" 比 "null" 方法工作得慢,尽管它们使用的内存是一样的。
【讨论】:
null 不是一种方法,并且您没有对数组列表 object 做任何事情。您只是比其他方式稍早地丢弃了对它的 reference。当你重新进入循环并为变量分配一个新的数组列表时,你也丢弃了旧的引用。