在我的程序中,我执行一些由MyParameter
对象参数化的任务(我调用doTask(MyParameter parameter)
来运行任务)。
从程序的开始到结束,我可以创建很多任务(至少几百万个),但是我只想运行其中的一个(如果任务已经执行,那么方法什么也不做)
目前,我正在使用HashSet
存储已执行任务的MyParameter
对象,但如果MyParameter
对象是100字节,并且如果我在程序10M任务中运行,则至少在内存中是1GB…)
如何优化它,尽可能少地使用内存?
非常感谢大家
最佳答案
如果你只需要知道一个特定的MyParameter
是否已经被处理过,去掉HashSet
并使用BitSet
代替。
基本上,如果你只需要知道一个特定的MyParameter
是否完成了,那么在集合中存储整个MyParameter
是过度的-你只需要存储一个位,其中0
表示“未完成”,而1
表示“完成”。这正是aBitSet
的设计目的。MyParameter
值的散列可能是唯一的,否则当前使用HashSet
的方法是没有意义的如果是,则可以使用每个hashCode()
的MyParameter
作为位集的索引,使用相应的位作为给定MyParameter
是否完成的指示器。
这可能没有什么意义,所以下面是一个基本的实现。(请随意用实际用于生成for
s的任何内容替换numParameters
循环、getParameter()
、MyParameter
等)
BitSet doneSet = new BitSet();
for (int i = 0; < numParameters; ++i) {
MyParameter parameter = getParameter(i);
if (!doneSet.get(parameter.hashCode())) {
doTask(parameter );
doneSet.set(parameter.hashCode());
}
}
这种方法的内存使用情况有点取决于
BitSet
是如何在内部实现的,但我希望它比简单地将所有MyParameters
存储在HashSet
中要好得多。事实上,如果您在处理对象后确实需要挂起它们,因为它们包含处理的结果,那么您可以通过在
MyParameter
中仅存储MyParameter
的结果部分来节省空间(如果这样的事情是可能的,那么您的问题并不能说明这一点)。另一方面,如果在处理完每个
HashSet
之后,确实需要它们的完整性,那么您已经尽力了。通过将它们存储为MyParameter
的向量(即可扩展数组),您可能可以在内存方面做得更好一些(这避免了使用MyParameters
时固有的一些内存开销),但由于扩展向量所需的时间和O(n)搜索时间,这将导致速度损失。关于java - 整个程序中的独特任务,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16310327/