【问题标题】:ArrayList and HashSet insert performance test result confuse meArrayList 和 HashSet 插入性能测试结果让我很困惑
【发布时间】:2013-02-10 18:45:38
【问题描述】:

我写了一个类来测试arraylist和hashset之间的插入性能,正如我所料,hashset的插入性能会比arraylist好很多(可能是书欺骗了我),但是测试结果让我很困惑

    HashSet<String> hashSet = new HashSet<String>();

    long start = System.currentTimeMillis();
    for (int i = 0; i < 900000; i++) {
        hashSet.add(String.valueOf(i));
    }

    System.out.println("Insert HashSet Time: " + (System.currentTimeMillis() - start));


    ArrayList<String> arrayList = new ArrayList<String>();

    start = System.currentTimeMillis();

    for (int i = 0; i < 900000; i++) {
        arrayList.add(String.valueOf(i));
    }
    System.out.println("Insert ArrayList Time: " + (System.currentTimeMillis() - start));

result:
Insert HashSet Time: 978
Insert ArrayList Time: 287

我多次运行这个主要方法,结果与此没有更多不同,插入arraylist时间比插入hashset时间短得多 谁能解释一下这个奇怪的结果。

【问题讨论】:

  • 字符串可能正在进行 JVM 缓存。例如。为 HashSet 创建字符串所花费的时间,然后在 ArrayList 中缓存和重用。如果颠倒顺序(例如先填充 ArrayList,然后填充 HashSet)会得到什么结果?

标签: java performance collections


【解决方案1】:

哈希集和列表是不同类型的数据结构。所以你应该在选择之前考虑一下你想用它们做什么。

哈希集

更长的插入时间

快速访问元素

列表

快速追加时间

元素访问时间长

列表更快,因为它可以在列表末尾添加元素,哈希集必须找到插入位置然后使元素可访问,这是更多的工作(时间),因为将其添加到末尾一个列表。

【讨论】:

  • 谢谢,我记得hashset在元素插入之前使用hashcode来确定元素位置,哦,我想我应该更仔细地看书~~非常感谢你
  • 列表有一个快速的追加时间; 插入时间取决于它们的内部实现方式。
【解决方案2】:

HashSet 由哈希表支持。如果您了解哈希表,您就会知道有一个哈希函数。当您在其中添加新元素时,还会发生碰撞处理(如果发生碰撞)。好吧 hashSet 不处理冲突,如果哈希相同,只需覆盖旧值。但是,如果达到容量,则需要调整大小,并可能重新散列。会很慢。

ArrayList 只是将对象附加到列表的末尾。如果达到大小,它会调整大小。

【讨论】:

    【解决方案3】:

    数据结构和算法的确切性能特征是高度特定于机器和实现的。但是,ArrayList 插入速度比HashSet 插入速度快一个常数对我来说并不奇怪。要插入ArrayList,您只需在数组中的特定索引处设置一个值。要插入哈希集中,您需要计算插入项目的哈希码并将其映射到数组索引,检查该索引并可能根据您找到的内容执行一些操作,最后插入到数组中。此外,HashSet 的内存局部性会更差,因此您会更频繁地发生缓存未命中。

    还有数组调整大小的问题,这两种数据结构都需要这样做,但是两种数据结构都需要以大致相同的速率调整大小(并且哈希表调整大小可能也因常数因素而更昂贵,因为重新散列)。

    这两种算法都是恒定(预期)时间,但与数组列表相比,哈希表的作用要多得多。因此,它会因常数因素而变慢也就不足为奇了。 (同样,确切的差异很大程度上取决于机器和实现。)

    【讨论】:

      【解决方案4】:

      实际上,您得到了正确的结果。此外,正如上述答案所指出的,这些是不同类型的数据结构。比较它们就像比较自行车和汽车的速度。我认为插入HashSet 的时间必须多于插入ArrayList 的时间,因为HashSet 不允许重复键。所以我假设在插入之前必须一些在插入之前检查重复键以及如何处理它们,这使得它们与ArrayList相比要慢一些。

      【讨论】:

        【解决方案5】:

        hashset 插入性能会比arraylist 好很多

        你是从哪里得到这个想法的?
        HashSet 在搜索中的表现优于ArrayList,即:get()
        但在插入时,它们具有可比的性能。实际上ArrayList 更快,如果你在数组限制内(不需要调整大小)并且哈希函数不好

        【讨论】:

          猜你喜欢
          • 2011-02-01
          • 1970-01-01
          • 1970-01-01
          • 2014-08-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-29
          相关资源
          最近更新 更多