使用Java,假设v1.6。
我有一个集合,其中唯一索引是一个字符串,非唯一值是一个int。 我需要尽快对这个集合执行数千次查找。
我目前正在使用HashMap<String, Integer>
,但我担心Integer to int的装箱/拆箱会让它变慢。
我原本想过使用ArrayList<String>
加上int[]
。
即。而不是:
int value = (int) HashMap<String, Integer>.get("key");
我能做到
int value = int[ArrayList<String>.indexOf("key")];
有什么想法?有更快的方法吗?
P.S。我只会构建一次集合并且可能会修改一次,但每次我都知道大小,所以我可以使用String[]
而不是ArrayList
,但不确定是否有更快的方法来复制indexOf ... < / p>
答案 0 :(得分:13)
取消装箱很快 - 不需要分配。拳击是一个可能较慢的,因为它需要分配一个新对象(除非它使用一个池)。
你确定你真的遇到了问题吗?在您确实证明这是一个重大的打击之前,不要使您的代码复杂化。我非常怀疑它是。
有可用于基本类型的集合库,但我会坚持使用JRE中的普通HashMap,直到您进行了分析并检查这是否会导致问题。如果真的只有数千的查找,我非常怀疑这将是一个问题。同样,如果你是基于查询而不是基于加法(即你获取的次数比你添加的更多),那么装箱费用不会特别重要,只需拆箱,这很便宜。
我建议使用intValue()
而不是强制转换来将值转换为int
- 这样可以更清楚地显示(IMO)正在发生的事情。
编辑:要回答评论中的问题,当集合足够大时,HashMap.get(key)
将比ArrayList.indexOf(key)
更快。如果你实际上只有五个项目,那么列表可能会更快。我认为事实并非如此。
如果你真的,真的不想要装箱/拆箱,试试Trove(TObjectHashMap)。还有COLT要考虑,但我找不到合适的类型。
答案 1 :(得分:3)
通过使用indexOf方法进行的for循环,您可以从不必使用box / unbox获得的任何性能提升都被显着删除。
使用HashMap。此外,您不需要(int)强制转换,编译器会为您处理它。
数组的东西可以用数组中的少量项目,但HashMap也是如此......
你可以快速查找数组的唯一方法(这是不是一个真正的建议,因为它有太多的问题)是你使用String的hashCode来工作作为数组的索引 - 甚至不要考虑这样做! (我只提到它,因为你可能会通过谷歌找到一些东西来讨论它...如果他们不解释为什么它不好不再阅读它了!)
答案 2 :(得分:1)
我猜想HashMap可以提供更快的查找速度,但我认为这需要一些基准测试才能正确回答。
编辑:此外,没有涉及拳击,只是对已经存储的对象进行拆箱,这应该非常快,因为在该步骤中没有完成对象分配。所以,我认为这不会给你更多的速度,但你应该运行基准测试。
答案 3 :(得分:1)
我认为扫描你的ArrayList以找到你的“密钥”的匹配将比你的装箱/拆箱问题慢得多。
答案 4 :(得分:1)
既然你说它确实是一个瓶颈,我会建议Primitive Collections for Java;特别是,ObjectKeyIntMap看起来就像你想要的那样。
答案 5 :(得分:1)
如果构建地图一次又一次的成本无关紧要,您可能需要查看perfect hashing,例如Bob Jenkins' code。
答案 6 :(得分:0)
这里有一个小问题:您可以在列表中包含重复的元素。如果您真的想以第二种方式进行,请考虑使用Set。
话虽如此,您是否对两者进行了性能测试,看看是否比另一个更快?
编辑:当然,最受欢迎的Set类型(HashSet)本身由HashMap支持,因此切换到一个集合可能不是一个明智的改变。
答案 7 :(得分:0)
List.indexOf
将对列表进行线性扫描 - 通常是O(n)。二进制搜索将在O(log n)中完成工作。哈希表将在O(1)中完成。
在内存中包含大量Integer
个对象可能是个问题。但是String
s(String
和char[]
)也是如此。你可以做自己的自定义数据库风格的实现,但我建议首先进行基准测试。
答案 8 :(得分:0)
地图访问不会对查找进行拆箱,只有稍后对结果的访问才会使其变慢。
我建议为int引入一个带有getter的小包装器,例如SimpleInt。它保持int而不转换。构造函数并不昂贵,总体上比整数更便宜。
public SimpleInt
{
private final int data;
public SimpleInt(int i)
{
data = i;
}
// getter here
....
}