繁体   English   中英

迭代遍历TreeSet比迭代Java中的HashSet要慢吗?

[英]Is iterating through a TreeSet slower than iterating through a HashSet in Java?

我正在运行一些基准测试。 我的一个测试取决于顺序,所以我正在使用TreeSet。 我的第二个测试没有,所以我正在使用HashSet。

我知道TreeSet的插入速度较慢。 但是如何迭代所有元素呢?

从类似的帖子( Hashset vs Treeset ):

HashSet比TreeSet快得多(对于大多数操作,例如add,remove和contains,常量时间与日志时间相比),但不提供像TreeSet这样的排序保证。

HashSet的:

  • class为基本操作提供恒定的时间性能(添加,删除,包含和大小)。
  • 它不能保证元素的顺序会随着时间的推移而保持不变
  • 迭代性能取决于HashSet的初始容量加载因子
    • 接受默认加载因子是非常安全的,但您可能希望指定的初始容量大约是您希望该组增长的大小的两倍。

TreeSet中:

  • 保证基本操作的log(n)时间成本(添加,删除和包含)
  • 保证set的元素将被排序(升序,自然,或者你通过它的构造函数指定的元素)
  • 不提供迭代性能的任何调整参数
  • 提供了一些方便的方法来处理有序集合,如first()last()headSet()tailSet()

重点:

  • 两者都保证元素的无重复收集
  • 通常,将元素添加到HashSet然后将集合转换为TreeSet以进行无重复的排序遍历通常会更快。
  • 这些实现都不是同步的。 也就是说,如果多个线程同时访问一个集合,并且至少有一个线程修改了该集合,则必须在外部进行同步。
  • LinkedHashSet在某种意义上介于HashSetTreeSet之间。 实现为具有贯穿其的链表的哈希表,但是它提供了插入顺序的迭代,这与TreeSet保证的排序遍历不同

因此,使用的选择完全取决于您的需求,但我觉得即使您需要有序集合,您仍然应该更喜欢HashSet来创建Set,然后将其转换为TreeSet。

  • 例如, Set<String> s = new TreeSet<String>(hashSet);

TreeSets内部使用TreeMaps ,它是Red Black Trees (特殊类型的BST )。

BST Inorder Traversal是O(n)

HashSets内部使用HashMaps ,它使用array来保存Entry对象。

这里的遍历也应该是O(n)

除非你写一个基准测试,否则很难证明哪个更快。

如果你想要(几乎) HashSet的性能稳定排序,那么使用LinkedHashSet 你仍然会得到恒定时间的操作,而我认为TreeSet会让你获得对数时间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM