Better practice to re-instantiate a List or invoke clear()
使用Java(1.6)更好地在List上调用clear()方法还是重新实例化引用?
我有一个ArrayList,其中填充有未知数量的对象,并定期"刷新"-处理对象并清除列表。刷新后,列表将再次填满。刷新发生在随机时间。列表中的数字可能较小(10个对象)或较大(数百万个对象)。
因此最好使用" flush "调用clear()或new ArrayList()吗?
是否值得担心此类问题,还是让VM担心呢?我该如何看待Java的内存占用,以便自己完成这种事情?
任何帮助都将不胜感激。
主要要关心的是其他哪些代码可能引用了该列表。如果现有列表在其他位置可见,您是否希望该代码查看已清除列表,还是保留现有列表?
如果没有其他可以看到的列表,我可能会清除它-但不是出于性能原因;仅仅因为您描述操作的方式听起来比"创建新列表"更像是清除。
(当然,创建新列表并不需要旧列表将所有数组元素设置为null ...,但我怀疑这在大多数情况下是否有意义。)
您使用它的方式非常类似于使用队列的方式。当您处理队列中的项目时,在处理它们时会将其删除。
使用其中一个Queue类可能会使代码更优雅。
还有一些变体以可预测的方式处理并发更新。
list.clear()没有比新的XXList更好的了。
这是我比较性能的调查。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | import java.util.ArrayList; import java.util.List; public class ClearList { public static void testClear(int m, int n) { List<Integer> list = new ArrayList<>(); long start = System.currentTimeMillis(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { list.add(Integer.parseInt("" + j + i)); } list.clear(); } System.out.println(System.currentTimeMillis() - start); } public static void testNewInit(int m, int n) { List<Integer> list = new ArrayList<>(); long start = System.currentTimeMillis(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { list.add(Integer.parseInt("" + j + i)); } list = new ArrayList<>(); } System.out.println(System.currentTimeMillis() - start); } public static void main(String[] args) { System.out.println("clear ArrayList:"); testClear(991000, 100); System.out.println("new ArrayList:"); testNewInit(991000, 100); } } /*--* * Out: * * clear ArrayList: * 8391 * new ArrayList: * 6871 */ |
我认为如果Arraylist的刷新频率太高,例如它在循环中连续运行或某些事情,那么如果刷新不是太频繁,最好使用clear来创建一个新实例。从10个对象到数百万个对象,您可能可以为创建的每个新Arraylist设置一个介于中间的大小,这样该arraylist可以避免大量时间调整大小。