HashMap用作缓存时的性能问题

时间:2014-11-28 09:28:26

标签: java performance caching hashmap

案例1:

一个HashMap,包含1,00,000个条目

案例2:

两个HashMap个,每个条目有50,000个。

上述哪种情况会占用更多的执行时间和更多内存?或两者之间是否存在显着差异?

用两个HashMap个较少数量的条目替换一个HashMap大量条目是否可行?

4 个答案:

答案 0 :(得分:2)

使用单个哈希映射你会更好。

查找在哈希映射中非常有效,并且它们被设计为包含许多元素。如果你必须放置一些东西来搜索一个地图然后查看另一个地图,它总体上会更慢。一个,如果你没有在第一个中找到它。

(无论哪种方式,内存使用量都没有太大差异。)

如果它目前太慢,请检查您的.hashCode().equals()效率不高。

答案 1 :(得分:2)

两种情况下的内存要求应该相似(因为HashMap存储是一个条目数组,其大小是映射的容量,因此两个50K的数组将占用相同的空间作为一个数组100K)。

get()put()方法在两种情况下也应具有相似的性能,因为密钥的哈希码和匹配索引的计算不受映射大小的影响。唯一可能影响这些操作性能的是 映射到同一索引的平均键数,也应该与映射的大小无关,因为随着大小的增加,Entries数组会增长,因此每个索引的平均条目数应该保持不变。

另一方面,如果使用两个较小的地图,则必须添加逻辑以决定使用哪个地图。您可以尝试在第一张地图中搜索关键字,如果找不到,则在第二张地图中搜索。或者,您可以使用一个标准来确定使用哪个地图(例如,从A到M开始的字符串键将存储在第一个地图中,其余的存储在第二个地图中)。因此,地图上的每个操作都会产生额外的开销。

因此,我建议使用一个HashMap

答案 2 :(得分:1)

使用一个或两个HashMap之间的性能差异不应该太大,所以选择更简单的解决方案,单HashMap

但是既然你问这个问题,我认为你有性能问题。通常,使用HashMap作为缓存是一个坏主意,因为它保持对缓存对象的引用,因此基本上禁用垃圾收集。考虑重新设计缓存,例如使用SoftReference(标准Java API中的类),它允许垃圾收集器收集缓存的对象,同时仍然可以重用对象,只要它们不是垃圾回收爱好。

答案 3 :(得分:0)

正如大家所提到的,你应该使用一个哈希映射。如果您在使用100k条目时遇到问题,那么您的代码就会出现严重问题。 这里有一些关于哈希映射:

  1. 不要使用太复杂的对象作为键(在我看来,使用对象字符串作为键应该是你应该去的HashMap。
  2. 如果你试图使用一些复杂的对象作为密钥,请确保你的equals和hashCode方法尽可能高效,因为这些方法中的太多计算会大大降低hashmap的效率