好奇心和效率是这个问题的原因。在某些循环运行后我正在创建许多新的HashSet:
HashSet目前在类的顶部声明为:
private Set<String> failedTests;
然后在代码中,我只是在重新运行测试时创建一个新的failedTests HashSet:
failedTests = new HashSet<String>(16384);
我反复这样做,具体取决于测试的大小。我希望垃圾收集器能够最有效地处理旧数据。但是,我知道另一种选择是在最初创建HashSet:
private Set<String> failedTests = new HashSet<String>(16384);
然后每次循环清除HashSet。
failedTests.clear();
我的问题是在开销等方面最有效的方法是什么?我不知道clear()函数在里面做了什么 - 它是做同样的事情,将旧数据发送到垃圾收集器,还是它做了更有效的事情?另外,我给HashSet一个很大的初始容量缓冲,但是如果一个测试需要超过2 ^ 14个元素,那么.clear()
函数会将HashSet重新实例化为16384吗?
要添加,我找到了source code to clear() here。所以它至少是最坏情况的O(n)运算。
使用clear函数,我做了一个测试过程,完成时间为565秒。 使用GC处理它,测试在506秒内完成。
但它不是一个完美的基准,因为还有其他外部因素,如与计算机和网络的文件系统连接。但是整整一分钟确实感觉非常好。有没有人推荐一个适用于线/方法级别的特定分析系统? (我正在使用Eclipse Indigo)
答案 0 :(得分:6)
我不知道clear()函数在
中做了什么
它正在调用它在内部使用的clear()
表的HashMap
方法。在HashMap
clear()
范围内,public void clear() {
modCount++;
Entry[] tab = table;
for (int i = 0; i < tab.length; i++)
tab[i] = null;
size = 0;
}
方法定义如下:
tab[i] = null
它做了同样的事情,将旧数据发送到垃圾箱 收集,还是它做得更有效率?
HashSet
指出它使旧数据符合垃圾收集条件。
另外,我给HashSet一个很大的初始容量缓冲,但是 如果测试需要超过2 ^ 14个元素,那么.clear()函数 将HashSet重新实例化为16384?
不,不会。
这是在开销方面做到这一点的最有效方法, 等?
我想,Java垃圾收集器知道如何以最有效的方式完成工作。所以让垃圾收集器来处理这个问题。所以,我更愿意在每次需要时创建一个新的失败的测试{{1}}。
答案 1 :(得分:4)
重新创建HashSet效率更高。
1)如果HashSet容量增长到16384以上,则不会将其重置为初始容量
2)新的HashSet(16384)创建一个新的Entry [16384]数组,它是一个操作,它比逐个清空元素更有效,如清楚
for (int i = 0; i < table.length; i++)
tab[i] = null;