- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在研究 String.intern() 并且此方法会降低性能。我将 String.intern() 与 ConcurrentHashMap.putIfAbsent(s,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,这个文档说:
If a thread-safe implementation is not needed, it is recommended to use HashMap in place of Hashtable. If a thread-safe highly-concurrent implementation is desired, then it is recommended to use ConcurrentHashMap in place of Hashtable.
这是非常令人困惑的情况。它推荐 ConcurrentHashMap,但它使用 HashTable 虽然性能会下降。有谁知道为什么使用 ConcurrentHashMap 的 native HashTable 实现实例?
最佳答案
这里发生了很多事情:
您的基准测试有非常大的误差线。重复计数可能太小。这使得结果有问题。
您的基准测试似乎没有在每次运行后重置“interned string”缓存1。所以这意味着缓存在增长,每次重复都会以不同的条件开始。这可以解释错误栏...
您的 ConcurrentHashMap
在功能上不等同于 String::intern
。后者使用与 Reference
对象等效的原生方法来确保驻留字符串可以被垃圾回收。您的 ConcurrentHashMap
实现没有。为什么这很重要?
ConcurrentHashMap
存在大量内存泄漏。String.intern() slower than ConcurrentHashMap because String.intern() is native HashTable implementation.
没有。真正的原因是 native 实现以不同的方式做事:
intern
) 字符串池使用以 native 代码实现的自定义哈希表。请注意,这些内容在不同的 Java 版本中差异很大。
This is very confusing situation. It recommend ConcurrentHashMap, but it using HashTable although performance penalty.
现在你在谈论一个不同的场景,这与你正在做的事情无关。
请注意 String::intern
既不使用 HashTable
也不使用 HashMap
;见上文。
您找到的引述是关于如何从哈希表获得良好的并发性能的。您的基准是(AFAIK)单线程。对于串行用例,HashMap
将提供比其他更好的性能。
Does anyone have any idea about why used native
HashTable
implementation instance ofConcurrentHashMap
?
它不使用哈希表;往上看。它不是 HashTable
或 HashMap
或 ConcurrentHashMap
的原因有很多:
Reference
类的内存和 CPU 开销很大。最后,请注意不要关注错误的问题。如果你因为实习是你应用程序的瓶颈而试图优化实习,另一个策略是根本不实习。在实践中,它很少节省内存(尤其是与 G1GC 的字符串去重相比),也很少提高字符串处理性能。
总结:
String::intern
并未专门(甚至主要)针对速度进行优化。1 - 在原生 intern
情况下,我认为这是不可能的。
2 - 常规堆中的 Java 内存泄漏会影响长期的 GC 性能,因为保留的对象需要被 GC 重复标记和复制。也可能有副作用。
关于Java String.intern() 使用 HashTable 而不是 ConcurrentHashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56203500/
我最初构造了一系列嵌套的 ConcurrentHashMaps private final ConcurrentHashMap allInOne = new ConcurrentHashMap
我正在尝试使用 ConcurrentHashMap 初始化 ConcurrentHashMap private final ConcurrentHashMap > myMulitiConcurrent
为了提高工作效率,我尝试将数据保存在一个动态容器中。 我在 class 中初始化它与 private final ConcurrentHashMap allInOne = new Concur
我正在创建基于 Socket 的服务器-客户端预订服务,并且遇到有关将由多个线程访问的类的问题,是否需要扩展 ConcurrentHashMap 或创建变量 ConcurrentHashMap 是否足
从 Javadoc 我知道 ConcurrentHashMap.replace 是原子的,但是 ConcurrentHashMap.put 呢?我看到它们在源代码中的实现方式不同,但我无法弄清楚它们的
是 ConcurrentHashMap.get() 保证看到以前的ConcurrentHashMap.put()通过不同的线程?我的期望是,阅读 JavaDocs 似乎表明了这一点,但我 99% 确信
使用 ConcurrentHashMap,我发现 computeIfAbsent 比 putIfAbsent 慢两倍。这里是简单的测试: import java.util.ArrayList; imp
我有一个以下格式的 ConcurrentHashMap: ConcurrentHashMap> 现在在此 map 中,我想删除数组列表中的特定值。任何人都可以指导这一点。 编辑1:我有一张 map >
为什么 ConcurrentHashMap.Segment 和 ConcurrentHashMap.HashEntry 类是静态的?为什么要这样设计? 最佳答案 基本上所有不需要使用其封闭类属性的内部
在 ConcurrentHashMap 中通过键递增并发计数器时,使用常规 Int 作为值是否安全,还是我们必须使用 AtomicInteger?例如考虑以下两个实现 ConcurrentHashMa
我对java中的并发数据结构有疑问,特别是: 1) ConcurrentHashMap 2) HashMap 3) ConcurrentHashMap 如果我理解正确的话: 1) 读/写是线程安全的,
我正在尝试查看实际的 Java 文档,描述传递给 ConcurrentHashMap.computeIfAbsent 和 ConcurrentHashMap.computeIfPresent< 时可以
我有一个名为 SerializableL 的接口(interface)由 3 个不同的类实现: 产品 横幅 标签 我开始重构,想用多个方法调用替换多个段落。 public void load(Conc
一 JDK 中的 ConcurrentHashMap 在 JDK 8以前,HashMap 是基于数组 + 链表来实现的。整体上看,HashMap 是一个数组,但每个数组元素又是一张链表。 当向 Has
我想知道当我们在调整大小时尝试读取 ConcurrentHashMap 时可能发生的情况。 我知道在读取期间,第一次尝试总是不同步的。在第二次尝试中,它将尝试获取锁并重试。 但是,如果它在调整大小时发
在一个应用程序中,1 个线程负责不断更新映射,主线程定期读取映射,使用 ConcurrentHashmap 是否足够?或者我应该明确地锁定同步块(synchronized block)中的操作吗?任何
介绍 ConcurrentHashMap 技术是为了解决问题而生的,ConcurrentHashMap 解决了多个线程同时操作一个 HashMap 时,可能出现的内部问题。当多个线程同时操作一
我有一个由多个线程访问的键值映射: private final ConcurrentMap key_vval_map = new ConcurrentHashMap(); 我的自定义 get() 和
谁能告诉我这段代码出了什么问题?我要拔头发了! 如果我使用 HashMap 而不是 ConcurrentHashMap 则没有任何问题。代码使用JDK 5.0编译 public class MapTe
来自 ConcurrentHashMap 的源码 /** 171 * Number of unsynchronized retries in size and containsVal
我是一名优秀的程序员,十分优秀!