Posted by sdo
on December 9, 2005 at 9:28 AM PST
You'll never know what performs better until you test it under a variety of circumstances.
One of the things that always interests me is the relative performance of
the collection classes. Recently, I discovered a particular anomaly of
the ConcurrentHashMap class.
I've always considered the ConcurrentHashMap class as something to be
used in special cases: use a Hashtable, and if you notice a lot of
contention for your hashtable, then switch to a ConcurrentHashMap. Of
course, you always write your code in terms of the Map interface so that
such a switch will be trivial, right?
This conviction stems partly from habit, partly from the fact that I
strongly believe that simple code is faster (the Hashtable class is a much simpler implementation), and partly from some
microbenchmarks I've run showing that when there is little or no contention,
is a faster implementation of the Map interface than ConcurrentHashMap.
This is particularly true on recent VMs, which do a much better job at
uncontended lock acquisition. [On the other hand, the ConcurrentHashMap
greatly increases throughput when there is moderate to severe contetion
for the map.]
Recently I ran across
some newly written code that used ConcurrentHashMap in its initial implementation. It unit tested fine,
of course, and we ran some simple performance tests on it, and it was still fine. And
then we ran into an interesting test case, where we created thousands of
the ConcurrentHashMap objects at a time (each one embedded in an Http session
It turns out that the size of an empty ConcurrentHashMap object is
1272 bytes; an empty Hashtable object is just 96 bytes. So forget any
minor performance difference in storage and retrieval that might exist
between the two; in this case,
our GC times when using the ConcurrentHashMap dominated everything else.
A simple one line change in the code, and we were back in business.
Will you see this type of thing in your app? Maybe not -- it is admittedly an unusual use case of the collection classes.
But I like this example, since it reinforces my basic
programming principles: start by using the simpler code, be prepared for changes, and
don't expect that you'll understand the performance of your application
until you test it under a variety of circumstances.