【问题标题】:ArrayList.clear() vs ArrayList=null [duplicate]ArrayList.clear() vs ArrayList=null [重复]
【发布时间】:2018-02-28 18:05:49
【问题描述】:

哪些在 java 中运行得更快? 假设我想多次使用一个 ArrayList 但具有不同的值,那么是使用 clear() 方法还是将 arraylist 设置为 null 更好??

【问题讨论】:

    标签: java performance arraylist


    【解决方案1】:

    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 的目标大小并避免迭代清除,这个版本可能只会更快。
    • 但是当分配一个新数组时,之前的内存也必须被垃圾收集器清除。
    • 现在不一定。事实上,只要不再引用该对象,GC 就不会立即收集。它可能会发生,但前提是堆消耗接近其最大大小。由于该对象不再被引用,我们说它有资格被收集。它可能需要几毫秒或几秒钟。而 clear() 实现迭代所有元素以将它们设置为 null :for (int i = 0; i &lt; size; i++) elementData[i] = null;
    【解决方案2】:

    所以要知道这一点,我使用不同的方法运行此代码两次以清除数组。 首先我使用了 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。当你重新进入循环并为变量分配一个新的数组列表时,你也丢弃了旧的引用。
    猜你喜欢
    • 2013-03-24
    • 2021-12-19
    • 2013-01-17
    • 2014-09-17
    • 2015-08-02
    • 2013-07-20
    • 2019-10-07
    • 2011-12-24
    • 2011-10-01
    相关资源
    最近更新 更多