2011-12-30 66 views
1

我处理的一些生成的数据文件(百兆字节的),其含有几个G对象。我需要随机访问这些对象。我想,可能的实施可能是一个大的HashTable。我的程序是用Java编写的,看起来java.util.HashMap无法处理这个(不知何故它非常慢)。任何人都可以推荐解决方案来随机访问这些对象?建议用于随机访问大量对象(如哈希表)

+1

你想在这些对象上做什么操作?这个问题的答案很大程度上取决于这个。例如,你是否需要按排序顺序?你需要能够通过一些索引访问吗?你需要能够找到类似于其他物体的物体吗? – templatetypedef 2011-12-30 03:22:05

+2

你是否必须在记忆中这样做?你的地图有多大(即多少个键)? (什么是“G对象”?) – fge 2011-12-30 03:22:23

+0

也许你需要重新思考你的存储机制:如果有很多数据可以预处理它并将它存储在一个图形树或类似的东西中? (http://highscalability.com/neo4j-graph-database-kicks-buttox) – Rafe 2011-12-30 03:40:07

回答

4

如果HashMap极其缓慢,那么这两个最有可能的原因如下:

  • 您键类的hashCode()和/或equals(Object)方法可能是非常昂贵的。举例来说,如果你使用数组或一个集合作为一个键,hashCode()方法将访问每次你怎么称呼它的每一个元素equals方法做同样的平等键。

  • 您的关键类可能有一个很差的方法,该方法对程序使用的(不同的)键的相当大的百分比给出相同的值。当发生这种情况时,你会得到许多关键的冲突,并且当散列表变大时,这对性能可能会非常糟糕。

我建议你先看看这些可能性,然后再改变你的数据结构。


注:如果“几个G的对象”是指数十亿对象,那么你就会有麻烦拿着文件内容的记忆...除非你正在运行的机器上这个应用程序与GB的100的内存。我建议你做一些“信封”计算,看看你想做什么是可行的。

1

无论你的密钥,确保你通过hashCode()产生为每一个好的哈希。很多时候,哈希映射表现可以归咎于碰撞哈希。当发生冲突时,HashMap为碰撞对象生成一个链表。

如果你返回相同的哈希值的所有对象最坏情况下,HashMap的本质变成一个链表。这里是编写散列函数的好地方:http://www.javamex.com/tutorials/collections/hash_function_guidelines.shtml

0

几百MB不能容纳几十亿个对象,除非每个对象都有一点(这不是真正的对象恕我直言)。

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

取决于数据的布局,这是值得记住的是,随机访问是不是最有效的方式来缓存数据,即64个字节(取决于架构),如果缓存加载线的结构,不适合在内存中,基于记录的表格可能更有效率。