首先让我告诉你,我已经阅读了Java HashMap performance optimization / alternative之前提出的以下问题,我也有类似的问题。
我想要做的是从纽约时代文本中获取大量依赖项,这些文本将由stanford解析器处理以提供依赖关系并将依赖项与其分数一起存储在哈希映射中,即如果我看到依赖项两次,我将将得分从散列图增加1.
任务很快就开始了,大约每秒10个句子,但很快就会缩小。在30 000个句子中(假设每个句子中有10个单词,并且每个单词存储大约3-4个依赖项)在我的hashmap中大约有300 000个条目。
我如何才能提高hashmap的性能?我可以使用什么样的哈希键?
非常感谢 马蒂诺
编辑1:
好吧,伙计们,我可能错误地说了我的问题,而且我的项目中没有使用字节数组,但是在上面另一个人的类似问题中。我不知道他们用它是什么因此这就是我问的原因。其次:我不会发布代码,因为我认为它会让事情变得非常难以理解,但这里有一个示例:
用句子:“我要睡觉了”我有依赖: (我,上午,-1) (我,去,-2) (i到,-3) (我,去,-1) 。 。 。 (于,床,-1) 所有句子的依赖性(1 000 000个句子)将存储在散列图中。 如果我看到依赖关系两次,我将获得现有依赖关系的分数并添加1.
这就是它。一切都很好,但在hashmap(或检索)中添加句子的比例在这一行缩小: dependancyBank.put(newDependancy,dependancyBank.get(newDependancy)+ 1); 谁能告诉我为什么? 问候 马蒂诺
答案 0 :(得分:3)
Trove已优化了哈希映射。
但是,很多依赖于智能选择结构和密钥的哈希码。
这部分问题不明确:The task starts off really quickly, about 10 sentences a second but scales off quickly. At 30 000 sentences( which is assuming 10 words in each sentence and about 3-4 dependences for each word which im storing) is about 300 000 entries in my hashmap.
。但是你没有说出更大数据的性能。你的地图在增长,这很明显。 Hashmaps仅在理论上是O(1)
,在实践中,由于较少的缓存局部性以及由于重新散列导致的偶然跳跃,您将看到一些性能随大小而变化。因此,put()
和get()
次不会保持不变,但仍然应该接近它。也许您正在以不保证快速访问的方式使用hashmap,例如迭代它?在这种情况下,您的时间将随着大小线性增长,除非您更改算法,否则无法更改。
答案 1 :(得分:2)
Google'fastutil',你会发现一个卓越的解决方案,可以将对象键映射到分数。
答案 2 :(得分:0)
看看Guava多图:http://www.coffee-bytes.com/2011/12/22/guava-multimaps它们的设计基本上是为了保存所有映射到同一个键的内容列表。这可能会解决您的需求。
答案 3 :(得分:0)
我如何才能提高hashmap的性能?
如果每个get()或put()花费超过1微秒,你就有一个错误恕我直言。你需要确定为什么它的使用时间长。即使在最糟糕的情况下,每个对象都具有相同的hasCode,你也不会有这么糟糕的表现。
我可以使用哪种哈希键?
这取决于密钥的数据类型。它是什么?
最后是什么是byte [] a = new byte [2]; byte [] b = new byte [3];在上面发布的问题?
它们是字节数组。它们可以用作查找值,但可能需要不同的值类型。
答案 4 :(得分:0)
HashMap有一个重载的构造函数,它将初始容量作为输入。您看到的缩放是因为重新散列,在此期间HashMap几乎无法使用。为了防止频繁的重新散列,您需要从具有更大初始容量的HashMap开始。您还可以设置一个加载因子,指示在重新散列之前加载哈希值的百分比。
public HashMap(int initialCapacity)
。
在对象构造期间将初始容量传递给HashMap。在程序执行过程中,最好将容量设置为您希望在地图中添加的元素数量的近两倍。