Даг Ли чрезвычайно хорош в этих вещах, поэтому я не удивлюсь, если в свое время его ConcurrentyHashMap работает лучше, чем HashMap Джошуа Блоха.Однако, начиная с Java 7, первым автором HashMap стал и Дуг Ли.Очевидно, что теперь нет причин, по которым HashMap будет работать медленнее, чем его двоюродный брат.
Из любопытства я все равно провел некоторый тест.Я запускаю его под Java 7. Чем больше записей, тем ближе производительность.В конечном счете ConcurrentHashMap находится в пределах 3% от 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.
}