为什么在 HashMap 上调用 containsKey
比 get
慢?
测试:http://ideone.com/QsWXF (>15% 的差异,在 sun-jdk-1.6.0.17 上运行)
最佳答案
因为它[稍微]做了更多工作,请参阅 the OpenJDK 7 source .
请注意 containsKey
调用 getEntry
而 get
直接“进行魔术查找”。 我不知道为什么这样做,并且对 请参阅 John B 和 Ted Hopps 的评论,了解为什么会这样完成。getForNullKey
的使用/不使用感到更加困惑:
get
有一个针对空键的早期代码拆分(请注意,如果条目不存在,get
将返回 null
或者存在并存储了空值):
315 if (key == null)
316 return getForNullKey();
...
322 if (e.hash == hash &&
((k = e.key) == key || key.equals(k)))
323 return e.value;
虽然从 containsKey
调用的 getEntry
不会拆分为 getForNullKey
并且这里还有额外的工作来检查空键情况(对于链中扫描的每个条目):
366 if (e.hash == hash &&
367 ((k = e.key) == key || (key != null && key.equals(k))))
368 return e;
此外,containsKey
有额外的条件和方法调用(注意 getEntry
将返回一个 Entry 对象,如果该键存在,即使存储的值为 空
):
352 return getEntry(key) != null;
我想可以说 containsKey
会从“性能”方面获益 - 有一个专门的形式(以更少的 DRY 代码为代价),或者 getEntry
可以在 get
的带领下进行早期的空键检查.. 另一方面,可能有人认为 get
应该写成术语getEntry
;-)
快乐编码。
关于java - 为什么 HashMap containsKey 在 Sun JDK 中比 get 慢? (太阳-jdk-1.6.0.17),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7999546/