Why is calling containsKey
on a HashMap slower then get
?
Test: http://ideone.com/QsWXF (>15% difference, run on sun-jdk-1.6.0.17)
Because it does [ever so slightly] more work, see the OpenJDK 7 source.
Note that containsKey
calls getEntry
while get
directly "does the magic lookup". I do not know why it was done this way, and am further puzzled by the use/not use of See John B's and Ted Hopps's comments as to why this is done.getForNullKey
:
get
has an early code split for a null-key (note that get
will return null
if the entry doesn't exist or existed with a null value stored):
315 if (key == null)
316 return getForNullKey();
...
322 if (e.hash == hash &&
((k = e.key) == key || key.equals(k)))
323 return e.value;
While getEntry
, called from containsKey
, does not split to getForNullKey
and there is additional work here to check for the null-key case (for each Entry scanned in the chain):
366 if (e.hash == hash &&
367 ((k = e.key) == key || (key != null && key.equals(k))))
368 return e;
Also, containsKey
has the additional conditional and method call (note that getEntry
will return an Entry object, if said key exists, even if the stored value is null
):
352 return getEntry(key) != null;
I suppose it could be argued that containsKey
would benefit - in terms of "performance" - from having a specialized form (at the expense of less-DRY code), or that getEntry
could follow the lead of get
with an early null-key check .. on the other-hand, it might be argued that get
should be written in terms of getEntry
;-)
Happy coding.