gpt4 book ai didi

Java String.intern() 使用 HashTable 而不是 ConcurrentHashMap

转载 作者:行者123 更新时间:2023-11-29 04:09:04 25 4
gpt4 key购买 nike

我正在研究 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 实现实例?

最佳答案

这里发生了很多事情:

  1. 您的基准测试有非常大的误差线。重复计数可能太小。这使得结果有问题

  2. 您的基准测试似乎没有在每次运行后重置“interned string”缓存1。所以这意味着缓存在增长,每次重复都会以不同的条件开始。这可以解释错误栏...

  3. 您的 ConcurrentHashMap 在功能上不等同于 String::intern。后者使用与 Reference 对象等效的原生方法来确保驻留字符串可以被垃圾回收。您的 ConcurrentHashMap 实现没有。为什么这很重要?

    • 您的 ConcurrentHashMap 存在大量内存泄漏。
    • 引用机制在 GC 时间是昂贵的。 (虽然可能比内存泄漏更便宜2。)

String.intern() slower than ConcurrentHashMap because String.intern() is native HashTable implementation.

没有。真正的原因是 native 实现以不同的方式做事:

  • 内部表示不同。 native (intern) 字符串池使用以 native 代码实现的自定义哈希表。
  • 它必须处理影响 GC 性能的引用。
  • 还有字符串去重和其他方面的幕后互动。

请注意,这些内容在不同的 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 of ConcurrentHashMap ?

它不使用哈希表;往上看。它不是 HashTableHashMapConcurrentHashMap 的原因有很多:

  • 是它更加注重内存利用率。所有的 Java 哈希表实现都是内存消耗,这使得它们不适合通用字符串驻留。
  • 使用 Reference 类的内存和 CPU 开销很大。
  • 计算新创建的长度为 N 的字符串的散列是 O(N),这在驻留可能有数百/数千个字符长的字符串时非常重要。

最后,请注意不要关注错误的问题。如果你因为实习是你应用程序的瓶颈而试图优化实习,另一个策略是根本不实习。在实践中,它很少节省内存(尤其是与 G1GC 的字符串去重相比),也很少提高字符串处理性能。


总结:

  • 你在比较苹果和橘子。您的基于 map 的实现不等同于本地实习。
  • String::intern 并未专门(甚至主要)针对速度进行优化。
  • 通过关注速度,您忽略了内存利用率……以及内存利用率对速度的次要影响。
  • 考虑根本不实习的潜在优化。

1 - 在原生 intern 情况下,我认为这是不可能的。
2 - 常规堆中的 Java 内存泄漏会影响长期的 GC 性能,因为保留的对象需要被 GC 重复标记和复制。也可能有副作用。

关于Java String.intern() 使用 HashTable 而不是 ConcurrentHashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56203500/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com