道格·李(Doug Lea)非常擅长这些事情,所以如果他一度比约书亚·布洛赫(Joshua Bloch)的表现更好,我不会感到惊讶。然而,从Java 7开始,第一个@author也变成了Doug Lea。显然,现在没有理由比它的并发表亲慢。ConcurrentHashMap
HashMap
HashMap
HashMap
出于好奇,我还是做了一些基准测试。我在Java 7下运行它。参赛作品越多,性能越接近。最终在3%以内,这是非常了不起的。瓶颈实际上是内存访问,俗话说,“内存是新磁盘(磁盘是新磁带)”。如果条目在缓存中,则两者都将很快;如果条目不适合缓存,则两者都会很慢。在实际应用程序中,地图不必很大就可以与其他地图竞争驻留在缓存中。如果地图经常使用,则会对其进行缓存;如果不是,则不会缓存它,这是真正的决定因素,而不是实现(假设两者都由同一个专家实现)ConcurrentHashMap
HashMap
public static void main(String[] args)
{
for(int i = 0; i<100; i++)
{
System.out.println();
int entries = i*100*1000;
long t0=test( entries, new FakeMap() );
long t1=test( entries, new HashMap() );
long t2=test( entries, new ConcurrentHashMap() );
long diff = (t2-t1)*100/(t1-t0);
System.out.printf("entries=%,d time diff= %d%% %n", entries, diff);
}
}
static long test(int ENTRIES, Map map)
{
long SEED = 0;
Random random = new Random(SEED);
int RW_RATIO = 10;
long t0 = System.nanoTime();
for(int i=0; i<ENTRIES; i++)
map.put( random.nextInt(), random.nextInt() );
for(int i=0; i<RW_RATIO; i++)
{
random.setSeed(SEED);
for(int j=0; j<ENTRIES; j++)
{
map.get( random.nextInt() );
random.nextInt();
}
}
long t = System.nanoTime()-t0;
System.out.printf("%,d ns %s %n", t, map.getClass());
return t;
}
static class FakeMap implements Map
{
public Object get(Object key)
{
return null;
}
public Object put(Object key, Object value)
{
return null;
}
// etc. etc.
}