Во время работы над эталоном памяти некоторых высокопроизводительных структур данных я понял, что могу использовать ImmutableMap
только с небольшим рефакторингом.
Думая, что это будет улучшением, я бросил его в микс и с удивлением обнаружил, что он не только медленнее, чем HashMap
, но в однопоточной среде он выглядит медленнее, чем ConcurrentHashMap
!
Здесь вы можете увидеть полный эталон: https://bitbucket.org/snippets/dimo414/89K7G
Мясо теста довольно простое, время, необходимое для получения большого количества случайных строк, которые могут существовать на карте.
public static void timeAccess(Map<String,String> map) {
Random rnd = new Random(seed);
int foundCount = 0;
long start = System.nanoTime();
for(int i = 0; i < loop; i++) {
String s = map.get(RndString.build(rnd));
if(s != null)
foundCount++;
}
long stop = System.nanoTime() - start;
System.out.println("Found "+foundCount+" strings out of "+loop+" attempts - "+
String.format("%.2f",100.0*foundCount/loop)+" success rate.");
System.out.println(map.getClass().getSimpleName()+" took "+
String.format("%.4f", stop/1_000_000_000.0)+" seconds.");
System.out.println();
}
И работая с HashMap
, a ConcurrentHashMap
и ImmutableMap
, все, содержащие одни и те же значения, последовательно демонстрируют резкое замедление при использовании ImmutableMap
- часто более 15% медленнее. Чем более разреженная карта (т.е. Чем чаще map.get()
возвращает null), тем больше диспропорция. Здесь результат выполнения пробега:
Found 35312152 strings out of 100000000 attempts - 35.31 success rate.
HashMap took 29.4538 seconds.
Found 35312152 strings out of 100000000 attempts - 35.31 success rate.
ConcurrentHashMap took 32.1465 seconds.
Found 35312152 strings out of 100000000 attempts - 35.31 success rate.
RegularImmutableMap took 37.9709 seconds.
Является ли это документированной/ожидаемой проблемой? Guava Docs указывает, что Immutable***
более эффективен с точки зрения памяти, но ничего не говорит о скорости. Для замедления этой величины я склонен справляться с расходами на память и избегать Immutable***
, когда скорость является проблемой (а когда нет?). Я что-то пропустил?
Смотрите также: https://groups.google.com/forum/?fromgroups=#!topic/guava-discuss/I7yPpa5Hlpg