Java 具有良好性能的多重映射
在我的代码中,我有一个在几秒钟内被大量使用的映射。最初我有一个树形图,但当测试9000个条目时,我看到我的旧处理器融化了。这需要扩大规模。所以我转向HashMap,性能非常好 现在我正在改变我的设计,正在寻找一个多重地图。但是,我担心Java 具有良好性能的多重映射,java,performance,multimap,Java,Performance,Multimap,在我的代码中,我有一个在几秒钟内被大量使用的映射。最初我有一个树形图,但当测试9000个条目时,我看到我的旧处理器融化了。这需要扩大规模。所以我转向HashMap,性能非常好 现在我正在改变我的设计,正在寻找一个多重地图。但是,我担心get()端的性能会受到影响,因为它必须在所述的大映射上迭代,以找出匹配的键,并且当多次调用甚至同步时,它看起来会很慢 是否有一个好的多重映射可以处理如此大的值并具有很好的性能?在这个应用程序中,性能是至关重要的,因为可能有许多单独的大型映射处理非常大的工作负载,这
get()
端的性能会受到影响,因为它必须在所述的大映射上迭代,以找出匹配的键,并且当多次调用甚至同步时,它看起来会很慢
是否有一个好的多重映射可以处理如此大的值并具有很好的性能?在这个应用程序中,性能是至关重要的,因为可能有许多单独的大型映射处理非常大的工作负载,这使得“小”的性能损失成为非常大的问题
如果它可以被提取出来单独工作而没有任何依赖性,则会获得额外的积分 在我的一个问题中向我推荐的是Apache Commons MultiMap: 它是免费软件,所以您至少可以让源代码查看它,并且根据您的许可证情况,您可以修改它或单独使用它 它在内部使用ArrayList,但我想您可能可以将其更改为使用HashSet或其他东西。我将研究
createCollection(Collection coll)
方法
更新:事实上,番石榴的HashMultiMap似乎已经是我所说的了:
我查看了源代码,似乎每个值集合实际上都有一个哈希集作为后盾。选择在很大程度上取决于您想要做什么。有许多数据结构,其中一些在特定领域优于其他数据结构,反之亦然 我可以向你推荐潜在的候选人。如果完全读取,ImmutableMultiMap可能非常适合 如果您需要并发读/写,那么我将实现自己的multimap,可能使用ConcurrentHashMap和ConcurrentSkipListSet(您需要小心,因为使用非阻塞数据结构以这种方式创建的同步multimap和multimap之间的语义不同)。如果您使用ConcurrentSkipListSet,那么就可以使用二进制搜索,它比仅仅迭代更快 如果有很多行,也可以从使用ConcurrentHashMap和同步列表开始。这可以显著减少争用,这可能足以解决性能问题,而且很简单 当你提到你“在所说的大地图上反复挑选匹配的键”时,我想知道你是否使用了最好的数据结构。有没有一种方法可以避免这种迭代
注意,Guava包括多个具有不同性能特征的multimap实现。正如Zwei提到的,不可变多重映射比可变多重映射具有更好的性能。如果代码检查多重映射是否包含特定值,则SetMultimaps会更快;否则,ArrayListMultimap的性能会更好。我有一个要求,我必须有一个
映射,其中映射上的插入是并发的,并且也在相应的集合上,但是一旦从映射中使用了一个键,就必须将其删除,试想一下,如果一个作业每两秒钟运行一次,从一个特定的键消耗整个集,但插入是完全并发的,以便在作业开始时缓冲大多数值,那么下面是我的实现:
注意:我使用Guava的helper类映射来创建并发映射,而且,这个解决方案模拟了Java并发,在实践中如清单5.19所示:
import com.google.common.collect.MapMaker;
import java.util.concurrent.ConcurrentMap;
/**
* Created by IntelliJ IDEA.
* User: gmedina
* Date: 18-Sep-2012
* Time: 09:17:50
*/
public class LockMap<K extends Comparable>
{
private final ConcurrentMap<K, Object> locks;
public LockMap()
{
this(16, 64);
}
public LockMap(final int concurrencyLevel)
{
this(concurrencyLevel, 64);
}
public LockMap(final int concurrencyLevel, final int initialCapacity)
{
locks=new MapMaker().concurrencyLevel(concurrencyLevel).initialCapacity(initialCapacity).weakValues().makeMap();
}
public Object getLock(final K key)
{
final Object object=new Object();
Object lock=locks.putIfAbsent(key, object);
return lock == null ? object : lock;
}
}
import com.google.common.collect.MapMaker;
import com.google.common.collect.Sets;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
/**
* A general purpose Multimap implementation for delayed processing and concurrent insertion/deletes.
*
* @param <K> A comparable Key
* @param <V> A comparable Value
*/
public class ConcurrentMultiMap<K extends Comparable, V extends Comparable>
{
private final int initialCapacity;
private final LockMap<K> locks;
private final ConcurrentMap<K, Set<V>> cache;
public ConcurrentMultiMap()
{
this(16, 64);
}
public ConcurrentMultiMap(final int concurrencyLevel)
{
this(concurrencyLevel, 64);
}
public ConcurrentMultiMap(final int concurrencyLevel, final int initialCapacity)
{
this.initialCapacity=initialCapacity;
cache=new MapMaker().concurrencyLevel(concurrencyLevel).initialCapacity(initialCapacity).makeMap();
locks=new LockMap<K>(concurrencyLevel, initialCapacity);
}
public void put(final K key, final V value)
{
synchronized(locks.getLock(key)){
Set<V> set=cache.get(key);
if(set == null){
set=Sets.newHashSetWithExpectedSize(initialCapacity);
cache.put(key, set);
}
set.add(value);
}
}
public void putAll(final K key, final Collection<V> values)
{
synchronized(locks.getLock(key)){
Set<V> set=cache.get(key);
if(set == null){
set=Sets.newHashSetWithExpectedSize(initialCapacity);
cache.put(key, set);
}
set.addAll(values);
}
}
public Set<V> remove(final K key)
{
synchronized(locks.getLock(key)){
return cache.remove(key);
}
}
public Set<K> getKeySet()
{
return cache.keySet();
}
public int size()
{
return cache.size();
}
}
import com.google.common.collect.MapMaker;
导入java.util.concurrent.ConcurrentMap;
/**
*由IntelliJ IDEA创建。
*用户:gmedina
*日期:2012年9月18日
*时间:09:17:50
*/
公共类锁图
{
私有最终ConcurrentMap锁;
公共锁图()
{
这(16,64);
}
公共锁图(最终int并发级别)
{
这(第64级);
}
公共锁图(最终int并发级别、最终int初始容量)
{
locks=new MapMaker().concurrencyLevel(concurrencyLevel).initialCapacity(initialCapacity).WeakValue().makeMap();
}
公共对象getLock(最终K密钥)
{
最终对象=新对象();
Object lock=locks.putIfAbsent(键,对象);
返回lock==null?对象:lock;
}
}
导入com.google.common.collect.MapMaker;
导入com.google.common.collect.set;
导入java.util.Collection;
导入java.util.Set;
导入java.util.concurrent.ConcurrentMap;
/**
*用于延迟处理和并发插入/删除的通用多映射实现。
*
*@param一个可比较的键
*@param A可比值
*/
公共类ConcurrentMultiMap
{
私人最终能力;
私有最终锁图锁;
私有最终ConcurrentMap缓存;
公共ConcurrentMultiMap()
{
这(16,64);
}
公共ConcurrentMultiMap(最终int ConcurrentLevel)
{
这(第64级);
}
公共ConcurrentMultiMap(最终整数并发级别,最终整数初始容量)
{
这个.initialCapacity=initialCapacity;
cache=new MapMaker().concurrencyLevel(concurrencyLevel).initialCapacity(initialCapacity).makeMap();
锁=新锁映射(并发级别,初始容量);
}
公开作废认沽权(最终K键,最终V值)
{
已同步(锁。getLock(键)){
Set=cache.get(key);
if(set==null){
set=Sets.newHashSetWithExpectedSize(初始容量);
cache.put(key,set);
}
增加(价值);
}
}
公共void putAll(最终K键、最终集合值)
{
已同步(锁。getLock(键)){
Set=cache.get(key);
if(set==null){
set=Sets.newHashSetWithExpectedSize(初始容量);
cache.put(key,set);
}
set.addAll(值);
}
}
公共集删除(最终K键)
{
已同步(锁。getLock(键
private Multimap<Phase, ResultingState> phaseResults = HashMultimap.create();
/**
* @param withState is the state to be verified.
* @param onPhase is the phase to be verified.
* @return Whether the given result was reported in the given phase.
*/
public boolean wasReported(ResultingState withState, Phase onPhase) {
return phaseResults.containsKey(onPhase) && phaseResults.get(onPhase).contains(withState);
}
/**
* @param resultingState is the resulting state.
* @return Whether the given resulting state has ever been reported.
*/
public boolean anyReported(ResultingState resultingState) {
return phaseResults.values().contains(resultingState);
}