Я занимаюсь исследованием String.intern (), и у этого метода есть снижение производительности.Я сравнил String.intern () с ConcurrentHashMap.putIfAbsent (s) с Microbenchmark.Используется Java1.8.0_212, Ubuntu 18.04.2 LTS
@Param({"1", "100", "10000", "1000000"})
private int size;
private StringIntern stringIntern;
private ConcurrentHashMapIntern concurrentHashMapIntern;
@Setup
public void setup(){
stringIntern = new StringIntern();
concurrentHashMapIntern = new ConcurrentHashMapIntern();
}
public static class StringIntern{
public String intern(String s){
return s.intern();
}
}
public static class ConcurrentHashMapIntern{
private final Map<String, String> map;
public ConcurrentHashMapIntern(){
map= new ConcurrentHashMap<>();
}
public String intern(String s){
String existString = map.putIfAbsent(s, s);
return (existString == null) ? s : existString;
}
}
@Benchmark
public void intern(Blackhole blackhole){
for(int count =0; count<size; count ++){
blackhole.consume(stringIntern.intern("Example "+count));
}
}
@Benchmark
public void concurrentHashMapIntern(Blackhole blackhole){
for(int count =0; count<size; count++){
blackhole.consume(concurrentHashMapIntern.intern("Example " +count));
}
}
Результат, как и ожидалось.ConcurrentHashMap быстрее, чем String.intern () при поиске строки.
Benchmark (size) Mode Cnt Score Error Units
MyBenchmark.concurrentHashMapIntern 1 avgt 5 0.056 ± 0.007 us/op
MyBenchmark.concurrentHashMapIntern 100 avgt 5 6.094 ± 2.359 us/op
MyBenchmark.concurrentHashMapIntern 10000 avgt 5 787.802 ± 264.179 us/op
MyBenchmark.concurrentHashMapIntern 1000000 avgt 5 136504.010 ± 17872.866 us/op
MyBenchmark.intern 1 avgt 5 0.129 ± 0.007 us/op
MyBenchmark.intern 100 avgt 5 13.700 ± 2.404 us/op
MyBenchmark.intern 10000 avgt 5 1618.514 ± 460.563 us/op
MyBenchmark.intern 1000000 avgt 5 1027915.854 ± 638910.023 us/op
String.intern () медленнее, чем ConcurrentHashMap, поскольку String.intern () является встроенной реализацией HashTable.А затем прочитайте javadoc о HashTable, эта документация гласит:
Если поточно-ориентированная реализация не требуется, рекомендуется использовать HashMap вместо Hashtable.Если требуется высококонкурентная реализация, ориентированная на многопотоковое исполнение, то вместо Hashtable рекомендуется использовать ConcurrentHashMap.
Это очень запутанная ситуация.Он рекомендует ConcurrentHashMap, но использует HashTable, хотя и снижает производительность.Кто-нибудь имеет представление о том, почему используется собственный экземпляр реализации HashTable ConcurrentHashMap?