在数组中重用hashmaps

时间:2011-12-22 12:43:55

标签: java performance

我持有一组哈希图,我想获得最大的性能和内存使用量,所以我想在数组中重新生成哈希图。

所以当数组中有一个不再需要的hashmap时,我想将新的hashmap添加到数组中,我只需清除hashmap并使用put()添加新值。

当我从数组中退出hashmap时,我还需要复制值。

我不确定这是否比每次创建new HashMap()更好。 什么更好?

更新

需要循环大约50百万个哈希映射,每个哈希映射具有大约10个键值对。如果数组20,000的大小,我只需要20,000个hashmaps而不是50 milion的新hashmaps()

7 个答案:

答案 0 :(得分:1)

对这种方法要非常小心。虽然回收对象在性能上可能更好,但是通过多次修改相同的引用可能会遇到麻烦,如以下示例所示:

public class A {
    public int counter = 0;

    public static void main(String[] args) {

         A a = new A();
         a.counter = 5;
         A b = a; // I want to save a into b and then recycle a for other purposes
         a.counter = 10; // now b.counter is also 10
    }
}

我确信你明白了,但是如果你没有复制数组中对HashMaps的引用,那么它应该没问题。

答案 1 :(得分:0)

没关系。过早优化。当你有分析器结果告诉你实际花费大部分内存或CPU周期时,请回来

答案 2 :(得分:0)

完全不清楚为什么以这种方式重用地图会提高性能和/或内存使用率。就我们所知,它可能没什么区别,或者可能产生相反的效果。

您应该在最易读的代码中进行任何结果,然后进行配置文件,最后优化探查器突出显示为瓶颈的代码部分。

答案 3 :(得分:0)

在大多数情况下,您不会感到任何不同。

通常,地图条目的数量比地图对象的数量高很多。填充地图时,每个条目都会创建Map.Entry的实例。这是相对轻量级的对象,但无论如何你调用new。没有数据的地图本身也是轻量级的,所以除非你的地图应该容纳1-2个条目,否则你不会从这些技巧中获得任何好处。

底线。 忘记早熟优化。实施您的申请。如果您遇到性能问题,请查看应用程序,找到瓶颈并进行修复。我可以99%保证瓶颈永远不会在new HashMap()电话中。

答案 4 :(得分:0)

我认为你想要的是一个对象池类的东西,你从对象池得到一个对象(在你的情况下,它的HashMap),执行你的操作,如果不再需要那个对象,你把它放回去在游泳池里。

检查对象池设计模式,进一步参考检查此链接:

http://sourcemaking.com/design_patterns/object_pool

答案 5 :(得分:0)

您遇到的问题是大多数对象都是HashMap中的Map.Entry对象。虽然您可以回收HashMap本身(及其数组),但这些只是对象的一小部分。解决这个问题的一种方法是使用来自javolution的FastMap,它可以回收所有内容并支持管理生命周期(它旨在通过这种方式最大限度地减少垃圾)

我怀疑最有效的方法是使用EnumMap(如果你已知关键属性)或POJO,即使大多数字段都没有使用。

答案 6 :(得分:0)

重用HashMap时存在一些问题。

  • 即使密钥和值数据不占用内存(从其他地方共享),Map.Entry对象也会主导内存使用但不会被重用(除非你做了一些特别的事情)。
  • 由于代际GC,通常将旧对象指向新的是昂贵的(并且相对难以看到正在发生的事情)。如果要保留数百万这些,可能不是问题。
  • 更复杂的代码更难以优化。所以保持简单,然后做大的优化,这可能涉及改变数据结构。