0

在我的程序中,我执行了一些由MyParameter对象参数化的任务(我调用doTask(MyParameter parameter)以运行任务)。

从程序的开始到结束,我可以创建很多任务(至少几百万)但我只想每个运行一次(如果一个任务已经执行,该方法什么都不做)

目前,我正在使用 aHashSet来存储MyParameter已经执行的任务的对象,但是如果MyParameter对象是 100 字节,并且如果我在我的程序中运行 10M 任务,那么它至少在内存中是 1GB ...)

我该如何优化它,以使用尽可能少的内存?

非常感谢各位

4

2 回答 2

1

如果您只需要知道某个特定是否MyParameter已被处理,请放弃HashSet并使用 aBitSet代替。

基本上,如果您只需要知道某个特定是否MyParameter已完成,那么将整个存储MyParameter在集合中是多余的 - 您只需要存储一个位,其中0表示“未完成”并1表示“完成”。这正是 aBitSet的设计目的。

您的值的哈希MyParameter值可能是唯一的,否则您当前使用 a 的HashSet方法毫无意义。如果是这样,那么您可以使用hashCode()每个MyParameter作为位集的索引,使用相应的位作为给定MyParameter是否完成的指示符。

这可能没有多大意义,所以下面是一个基本的实现。(请随意用您实际用于生成s 的任何内容替换for循环、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内部如何实现,但我希望它比简单地将所有内容存储MyParametersHashSet.

事实上,如果您在处理对象后确实需要挂起MyParameter对象,因为它们包含处理的结果,那么您可以通过仅存储结果部分来节省空间MyParameterHashSet如果可能的话 -你的问题没有说清楚)。

另一方面,如果在处理完它们后你真的需要它们MyParameter的全部,那么你已经在尽你所能做到最好了。您可以通过将它们存储为一个向量(即可扩展数组)MyParameters(这避免了使用 a 固有的一些内存开销HashSet)来在内存方面做得更好,但这会因需要时间而导致速度损失扩展向量和 O(n) 搜索时间。

于 2013-05-01T05:08:55.583 回答
0

TreeSet 将比 HashSet 提供更好的内存性能,但代价是 log(n) 查找。

您可以使用 NoSql 键值对存储,例如CassandraLevelDB,它们本质上是外部哈希表。

您也许可以压缩MyParameter表示,但如果它目前只有 100 字节,那么我不知道您能得到它多小。

于 2013-04-30T23:19:31.020 回答