需要快速替代Java TreeMap <integer,character =“”>,它可以保存多个映射而不会减速</integer,>

时间:2011-10-06 17:16:18

标签: java object primitive treemap sorted

我正在编写一个使用TreeMap的Java程序,一旦有数十万个整数字符映射,性能就会慢下来。

我想知道是否有某种类型的排序集实现的实现可以使用int和char原语,并且具有类似“headMap”和“tailMap”函数的功能。

我现在正在看Trove。我还查看了一个使用插入排序但不包括head和tail函数的链表的实现。我认为带有插入排序的链表比树慢,但不是吗?

9 个答案:

答案 0 :(得分:2)

如果您正在寻找像TreeMap<Integer,Character>这样的替代品,并且如果您的整数键密集,那么数组将是最有效的。但它应该是char[]而不是int[],因为您要根据char - 键查找int。 然后我读了一些关于'基因组'的东西?!假设您想使用char代表Adenin,Guanin,Cytosin和Thymin(我不是专家)请记住char每个需要16位 - 远远超过您的需要四个不同的事情。也许你可以做像

那样的somenthing
...
public static final byte UNDEF = (byte)-1;
public static final byte ADENIN = 0;
public static final byte GUANIN = 1;
public static final byte CYTOSIN = 2;
public static final byte THYMIN = 3;
...
private byte[] genome = new byte[ 26000000 ]; // or which size ever
...

如果这仍然占用太多内存,那就会变得棘手:假设你不需要UNDEF值,你只需要2位就可以得到4个值,也就是说你可以用四个值存储你的序列每个字节的值最终需要大约6.5 MB。但是对于这样的事情,你需要做一些小小的事情......

答案 1 :(得分:1)

如果我理解了这个问题,你需要一个保留键顺序的数据结构,即char替换个人参考序列中char的位置。

我假设您通过增加排名顺序来处理这些项目。

现在,由于TreeMap正在实现Red-Black Tree,因此它具有基本操作的对数复杂性。

如果您只需按顺序迭代序列,则每次插入都会对性能产生严重影响。

如果我的假设是正确的,我会说你可以使用LinkedHashMap

正如javadoc所解释的那样:

  

此实现通常会将客户从未指定的客户端中删除   HashMap(和Hashtable)提供的混乱排序,没有   导致与TreeMap相关的成本增加。

这意味着您可以按照输入的顺序迭代元素,但基本操作与普通HashMap具有相同的复杂性,由于链接列表处理而导致性能下降。

您可以将其描绘为一个双链表所遍历的HashMap,该列表按照插入顺序连接键。

请注意,我没有解决您的序列是否适合内存的事实。另外,请注意LinkedHashMap将占用比简单HashMap更多的内存。

答案 2 :(得分:0)

如果您只想要更快的Map实施,您是否考虑过HashMap?这仍然使用对象,但如果最初创建(请参阅上一个链接中的构造函数的第三种形式),并且具有足够大的容量,这将允许比TreeMap更快地访问您的数据。

或者,如果您只对地图中类似SortedSet的行为感兴趣,则可以使用TreeSet获得更好的效果。

对于Trove,我并不熟悉它,但我怀疑你可以从Java提供的类中获得显着的性能增强,而不是只需要花费额外的努力来检查你需要的东西您的数据结构以及他们提供您不需要的功能所浪费的额外工作。

答案 3 :(得分:0)

史蒂夫写道,使用分析器检查TreeMap是罪魁祸首可能是值得的。

其他几个选项是:

  • 使用HashMapinitialCapacity

  • 如果您的密钥集密集,那么您可以使用int[]。那将是最快的。

答案 4 :(得分:0)

你看过PriorityQueue了吗? 它有一些有用的方法,并根据你定义的比较器对元素进行排序。

答案 5 :(得分:0)

要容纳大量元素,最好使用B-Tree。这种结构广泛用于数据库中以保存索引。例如在Oracle和MySQL上,如果我没有弄错的话。看看JDBM3。还应该存在其他实现。

答案 6 :(得分:0)

如果你知道这是你的性能瓶颈和/或内存问题 - 那么我会考虑使用你的TIntCharHashMap。过去,我已经使用了宝地图来提高性能并相当成功地降低了内存消耗。

请注意,密钥不会被排序,但您可以非常便宜地获得密钥的int[],然后您可以对其进行排序。因此,如果您只需要偶尔进行排序遍历,则可以根据需要对它们进行排序。

如果您发现丑陋(或性能受阻),您可以将TIntCharHashMap并将int[]排序到您自己的有序地图中 - 您只需要自己维护不变量。

我觉得有点不幸的是,特洛伊没有直接基于树的维护地图/集合类,但感谢它提供的工具。

答案 7 :(得分:0)

一种适用于非常大的有序映射的技术是使用SortedSet的组合来按排序顺序管理键,使用Map来管理实际的键值映射。通过这种方式,您可以使用headSet()和tailSet()快速迭代键,然后使用从集合返回的键来查找实际的映射。

我没有证据证明这项工作的原因,但根据我的经验,使用非常大的分类地图会快10倍。

答案 8 :(得分:0)

值得尝试 B-Tree 类似 Max Bolingbroke 的解决方案。