2

我一直对一些 yourkit 快照感到困惑,这似乎表明在特定堆栈hashmap.put()中被证明是昂贵的。

假设这张地图的关键是一个非常复杂的对象,它没有被覆盖equals()hashCode()

在某些情况下真的有可能HashMap.hash()或代价高昂吗?Object.hashCode()

4

4 回答 4

1

您说您的分析器指示put为热点,而不是哈希码计算。put不仅仅是哈希码的确定。特别是,如果地图非常大,就会做很多家务工作。put而且,如果您的代码除了调用大量次之外几乎没有其他作用,那么这自然会在分析器中显示为热点。不过,它的性能可能没有任何问题。

于 2013-08-02T16:16:36.093 回答
1

这在理论上是可能的,但极不可能。

如果您真的在使用Object.hashcode(),那么代表System.identityHashCode(Object)相对便宜。此外,身份哈希码不应该给你碰撞热点......除非你真的很不走运。

如果您在HashMap.hash()和中看到性能热点,Object.hashCode()那么原因可能是您只是在进行大量HashMap查找。

于 2013-08-02T16:07:00.597 回答
1

当然可以创建一个放入 HashMap 的成本很高的对象:

class Awful {
    @Override
    public int hashCode() {
        try {
            Thread.sleep(10000000);
        } catch (InterruptedException e) {
           Thread.currentThread().interrupt();
        }
        return 1;
    }
}

显然这是一个人为的例子,但我已经看到了在 Hibernate 支持的延迟加载对象上调用方法的实现。将所述对象放入列表会导致大量、非常昂贵的数据库查找。

在不覆盖hashCode()的情况下,该值是从对象的地址派生的,JVM 在调用方法时已经拥有该地址,因此它(尽可能好)是即时的。

于 2013-08-02T16:05:22.017 回答
0

我相信你的工具包并不总是值得信任的。在重度 JIT 优化分析器下,他们会感到困惑,并开始在尴尬的位置显示成本。

于 2015-05-11T07:43:16.893 回答