【问题标题】:what is faster hashset clear or new hashset? [duplicate]什么是更快的哈希集清除或新的哈希集? [复制]
【发布时间】:2011-12-20 02:21:45
【问题描述】:

假设我已经定义了一个HashSet<String> set
在性能方面什么更好:

set.clear;

set = new HashSet<String>();

编辑:我检查的原因是目前我的代码有第二个选项,但我想将其更改为第一个以设置 final

【问题讨论】:

  • 你可以用代码测量它
  • 简而言之,如果它更“空间关键”,则使用“clear()”;否则只需创建一个对象。垃圾收集器作为低优先级线程运行,不保证及时回收,尤其是当集合很大时,在您的情况下。

标签: java performance hashmap hashset


【解决方案1】:

虽然clear 的性能可能更高,但这取决于集合的大小。在实践中,这不太可能对应用程序的性能产生显着影响。即使在围绕这个函数的代码行中,性能也会受到 JIT 编译等其他因素的支配。

重要的是设计质量,这将使您在分析代码后轻松地重构性能。在大多数情况下,避免难以跟踪的状态更改很重要,并且创建一个新的 HashSet 比重复使用 HashSet 更好。

【讨论】:

    【解决方案2】:

    我建议你做你认为最清晰和最简单的事情。

    尝试重用 HashSet 的问题是内部使用的大多数对象都没有被回收。如果你想要这个使用 Javolution 的 FastSet http://javolution.org/target/site/apidocs/javolution/util/FastSet.html

    HashSet 不是最有效的集合集合,因此如果您真的关心这种级别的微优化,您可能会发现不同的集合更适合您的用例。然而,在 99% 的情况下,它都很好,也是哈希集最明显的选择,我怀疑你如何使用它并不重要。

    【解决方案3】:

    这听起来像是您应该避免进行的优化,除非您已经分析了问题。如果没有,那么一般而言,您最好按照预期的方式使用 API(即调用 clear())。

    如果您使用 clear() 或 new HashMap() 分析了代码区域中的问题,那么您最好寻找更快的 HashSet 替代方案。除非您需要在集合级别保证唯一性,否则 LinkedList 或 ArrayList 将始终更快。

    【讨论】:

      【解决方案4】:

      HashSet#clear 将遍历支持 HashMap 中的所有元素并将它们设置为 null。

      我想set = new HashSet&lt;String&gt;() 会更快,因为n 的值越来越大。

      【讨论】:

        【解决方案5】:

        HashSetHashMap 支持,对clear() 的调用将重新路由到HashMap.clear()。即(至少在 Java 1.6 中)实现如下:

        /**
         * Removes all of the mappings from this map.
         * The map will be empty after this call returns.
         */
        public void clear() {
            modCount++;
            Entry[] tab = table;
            for (int i = 0; i < tab.length; i++)
                tab[i] = null;
            size = 0;
        }
        

        所以我想,如果您的旧 HashSet 非常大,那么新的 HashSet 会快很多。

        【讨论】:

        • 我做了很多算法优化和微基准测试。作为一个单一的操作,一个简单的内存分配比 HashMap.clear() 快得多。如果您进行频繁分配,例如在某种计算算法中每秒数千万,那么差异将不那么明显,但即便如此,分配一个新对象并让 GC 进行批量清理应该更便宜。
        【解决方案6】:

        HashSetclear 调用map.clear()

        这是

         /**
          621        * Removes all of the mappings from this map.
          622        * The map will be empty after this call returns.
          623        */
          624       public void clear() {
          625           modCount++;
          626           Entry[] tab = table;
          627           for (int i = 0; i < tab.length; i++)
          628               tab[i] = null;
          629           size = 0;
          630       }
        

        所以它肯定取决于 Set 的大小。但答案是在您的应用环境中对其进行基准测试

        注意:在本次演讲中提到 OpenJDK 实现

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-01
          • 1970-01-01
          • 1970-01-01
          • 2019-12-20
          • 1970-01-01
          • 2012-12-25
          相关资源
          最近更新 更多