对于较小的地图,HashMap速度更快

时间:2014-09-24 21:01:44

标签: java data-structures hashmap k-means

这可能是一个奇怪的问题,但它基于我得到的一些结果,使用Java Map - 在HashMap的情况下,当地图较小时,元素检索速度会更高吗?

我有一部分代码使用containsKey的{​​{1}}和get(key)方法,如果Map中的元素数量较小,它似乎运行得更快?是这样吗?

我的知识是HashMap使用一些哈希函数来访问地图的某个字段,并且有一些版本,其中该字段是对链表的引用(因为某些键可以映射到相同的值) ,或完全静态实现时,或映射到地图中的其他字段。

这是正确的 - 如果Map的元素较少,速度会更高吗?

我需要用一个具体的例子来扩展我的问题。

我有2个案例,两个元素的总数是相同的。

  • 在第一种情况下,我有10个HashMaps,我不知道元素是如何分布的。该部分算法的执行时间为141ms。
  • 在第二种情况下,我有25个HashMaps,相同的元素总数。执行相同算法的时间为69ms。

在这两种情况下,我都有一个遍历每个HashMaps的for循环,尝试查找相同的元素,并获取元素(如果存在)。

可执行时间是否较小,因为HashMap中的个别搜索较小,所以有和吗?

我知道这很奇怪,但是这种方式有点可能,或者我做错了什么?

考虑Map(Integer,Double)。很难说元素的分布是什么,因为它实际上是KMeans聚类算法的实现,元素是聚类质心的表示。这意味着它们将主要依赖于算法的初始化。元素的总数大部分都不一样,但我试图简化问题,如果这有误导性,那就很抱歉。

3 个答案:

答案 0 :(得分:2)

来自Java docs

  

此实现为基本提供了恒定时间性能   操作(获取和放置),假设散列函数分散了   桶中的元素。

换句话说,对于大型地图而不是小型地图,访问速度应该没有区别。例外情况是,如果项目发生大量冲突,理论上可能会因为添加更多冲突数据而降低性能。

如果这实际上是您注意到的实际问题,则应检查您输入的数据以及您正在使用的哈希函数(假设使用自定义数据类型)。尽量确保您没有插入具有重复哈希值的大量数据。如果这不起作用,那么很可能是由基准测试中的错误或硬件/操作系统级别问题(例如问题评论中提到的缓存问题)引起的

答案 1 :(得分:1)

碰撞次数对于减速是决定性的。

假设一个大小的数组,以大小为模的散列代码然后指向放置对象的索引。具有相同索引的两个对象发生碰撞。

具有相对于元素数量的大容量(数组大小)有帮助。

使用HashMap时,会有重载的构造函数和额外的设置。

public HashMap(int initialCapacity,
               float loadFactor)

使用指定的初始容量和加载因子构造一个空的HashMap。

你可以尝试一下。

对于与HashMap一起使用的特定键类,具有良好的hashCode也可以提供帮助。哈希码是一个单独的数学领域。

当然使用较少的内存有助于处理器/物理内存级别,但我怀疑在这种情况下有影响。

答案 2 :(得分:0)

您的时间安排是仅考虑get / containsKey的费用,还是您还在定时代码部分执行put?如果是这样,并且如果您使用默认构造函数(初始容量16,加载因子0.75),那么较大的哈希表将需要比较小的哈希表更频繁地调整自身大小。就像Joop Eggen在他的回答中所说,尝试使用构造函数中的初始容量,例如:如果您知道自己有N个元素,那么将初始容量设置为N / number_of_hash_tables或者沿着这些行设置的东西 - 这应该会导致越来越大的哈希表具有足够的容量以至于他们不会获胜需要调整大小