Java HashMap put性能
我一直对一些yourkit快照感到困惑,这些快照似乎表明,在特定的堆栈中,Java HashMap put性能,java,hash,hashmap,hashcode,yourkit,Java,Hash,Hashmap,Hashcode,Yourkit,我一直对一些yourkit快照感到困惑,这些快照似乎表明,在特定的堆栈中,hashmap.put()被证明是昂贵的 假设此映射的键是一个非常复杂的对象,它没有覆盖equals()或hashCode() 在某些情况下,HashMap.hash()或Object.hashCode()是否真的可能代价高昂?当然可以创建一个代价高昂的对象放入HashMap: class Awful { @Override public int hashCode() { try {
hashmap.put()
被证明是昂贵的
假设此映射的键是一个非常复杂的对象,它没有覆盖equals()
或hashCode()
在某些情况下,
HashMap.hash()
或Object.hashCode()
是否真的可能代价高昂?当然可以创建一个代价高昂的对象放入HashMap:
class Awful {
@Override
public int hashCode() {
try {
Thread.sleep(10000000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return 1;
}
}
显然,这是一个人为的例子,但我见过在Hibernate支持的、惰性加载的对象上调用方法的实现。将所述对象放入列表会导致大量、相当昂贵的数据库查找
如果不重写
hashCode()
,则该值是从对象的地址派生的,JVM在调用该方法时已经拥有该地址,因此它(与)是即时的。这在理论上是可能的,但不太可能
如果您确实在使用Object.hashcode()
,那么这将委托给相对便宜的System.identityHashCode(Object)
。此外,身份哈希代码不应该给您冲突热点。。。除非你真的很倒霉
如果您在
HashMap.hash()
和Object.hashCode()
中看到性能热点,那么可能是因为您正在进行大量的HashMap
查找 您说您的分析器将put
指示为热点,而不是hashcode计算put
不仅仅是hashcode的确定。特别是,如果地图非常大,将会有很多家务工作要做。如果您的代码除了调用put
之外几乎不做其他事情,那么很自然,这将作为热点显示在分析器中。不过,它的性能可能没有什么问题。我相信您的工具包并不总是值得信任的。在严重的JIT优化探查器下,它们会感到困惑,并开始在尴尬的位置显示成本。大多数对象的默认哈希代码是它们在内存中的地址,因为两个对象无法共享该空间。此值是唯一的。此外,它是一个本机函数,因此应该非常快。如果未覆盖该键,则将使用默认的hashCode
。这只是返回项目的内存位置,它应该相当便宜。这个问题将是不公平的,因为存在大量对象冲突,这会对HashMap
@borisspider的性能产生巨大的、有害的影响。两个对象具有相同的内存地址,从而不太可能发生冲突,这不是不可能的吗?我假设Java的哈希算法非常好。@LeeMeador哈希代码在int
范围内。还有更多的地址…@Boristeider一个整数有40亿个值(有些地方有40亿个)。大多数应用程序占用的内存少于4GB。诚然,不一定是相邻的,但仍然。。。我想不太可能发生冲突。是的。这没有道理。看起来这是yourkit的错误/问题。一旦我用列表结构交换地图,成本就会分配到其他堆栈。肯定是你的球衣打得不好。