建议随机访问大量对象(如哈希表)

时间:2011-12-30 03:20:08

标签: java hashmap random-access

我正在处理一些生成的数据文件(数百MB),其中包含多个G个对象。我需要随机访问这些对象。我猜一个可能的实现可能是一个很大的HashTable。我的程序是用Java编写的,似乎java.util.HashMap无法处理这个问题(不知怎的,它非常慢)。任何人都可以推荐一个随机访问这些对象的解决方案吗?

3 个答案:

答案 0 :(得分:4)

如果HashMap非常慢,那么两个最可能的原因如下:

  • 您的密钥类上的hashCode()和/或equals(Object)方法可能非常昂贵。例如,如果您使用数组或集合作为键,hashCode()方法将每次访问每个元素,并且equals方法将执行同等的钥匙。

  • 您的密钥类可能有一个较差的hashCode()方法,该方法为程序使用的很大一部分(不同)密钥提供相同的值。当发生这种情况时,会发生许多关键冲突,当哈希表变大时,这可能对性能非常不利。

我建议您在更改数据结构之前首先查看这些可能性。


注意:如果“几个G对象”意味着数十亿个对象,那么您将无法将文件的内容保存在内存中...除非您在具有100 GB千兆字节RAM的计算机上运行此应用程序。我建议你做一些“信封背面”的计算,看看你试图做的是否可行。

答案 1 :(得分:1)

无论你的密钥是什么,请确保通过hashCode()为每个密钥生成一个好的哈希值。很多时候糟糕的HashMap性能可归咎于碰撞哈希。当发生碰撞时,HashMap会为碰撞对象生成链接列表。

如果您为所有对象返回相同的哈希,最糟糕的情况是,HashMap基本上成为链表。这是编写哈希函数的良好起点:http://www.javamex.com/tutorials/collections/hash_function_guidelines.shtml

答案 2 :(得分:0)

几百MB不能容纳几十亿个对象,除非每个对象都有一点(实际上它不是IMHO的对象)。

我如何处理这个问题是使用内存映射文件映射数据内容并在另一个内存映射文件中构建自己的哈希表(这需要您扫描数据一次以构建密钥)

根据数据的布局,值得记住的是随机访问不是缓存数据的最有效方式,即缓存加载的64字节行(取决于体系结构)以及结构是否适合内存,基于记录的表可能更有效。