Jac*_*ack 2 java performance hashmap load-factor
我正在使用大型(数百万)hashmap实现Java,实际上构建的容量为10.000.000,加载因子为.75,它用于缓存一些值
因为缓存的值随着时间的推移变得无用(不再被访问)但是我无法删除无用的值,而我想在它的性能开始降低时完全清空缓存.我该怎么决定什么时候做好呢?
例如,当它达到750万个元素时,我应该清空它的1000万容量和.75 因为我尝试了各种阈值,但我希望有一个分析值.
我已经测试了这样一个事实:当它非常饱满时将它移除是对性能的提升(擦除之后的前2-3次算法迭代只是填充它,然后它开始比擦除之前更快地运行)
编辑:附加信息
hashmap长按键并浮动为值.它包含内容的缓存关联,因为它是我想缓存它们的标记向量的点积(以提高性能).
所以基本上我所做的是long使用2个内容的哈希码计算密钥:
static private long computeKey(Object o1, Object o2)
{
int h1 = o1.hashCode();
int h2 = o2.hashCode();
if (h1 < h2)
{
int swap = h1;
h1 = h2;
h2 = swap;
}
return ((long)h1) << 32 | h2;
}
Run Code Online (Sandbox Code Playgroud)
并使用它来检索存储的值.会发生的是,因为它是一个层次化的聚类内容被合并,并且不再需要它们与其他内容的相关值..这就是为什么我想不时擦除哈希映射,以避免由于其中无用的值而导致的降级.
WeakHashMap当仍然需要时,使用遗嘱会无法预测地删除数据.我无法控制它.
谢谢
为什么不使用LRU Cache?从Java的LinkedHashMap文档:
提供了一个特殊的构造函数来创建链接的哈希映射,其迭代顺序是其条目最后一次访问的顺序,从最近访问到最近(访问顺序).这种地图非常适合构建LRU缓存.调用put或get方法会导致访问相应的条目(假设它在调用完成后存在).putAll方法为指定映射中的每个映射生成一个条目访问,按照指定映射的条目集迭代器提供键 - 值映射的顺序.没有其他方法可以生成入口访问.特别是,对集合视图的操作不会影响后备映射的迭代顺序.
所以基本上,每当你的地图变得太大时,只需删除迭代器为你提供的前x个值.
请参阅文档removeEldestEntry以自动完成此操作.
这是代码,演示:
public static void main(String[] args) {
class CacheMap extends LinkedHashMap{
private int maxCapacity;
public CacheMap(int initialCapacity, int maxCapacity) {
super(initialCapacity, 0.75f, true);
this.maxCapacity = maxCapacity;
}
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
return size()>maxCapacity;
}
}
int[] popular = {1,2,3,4,5};
CacheMap myCache = new CacheMap(5, 10);
for (int i=0; i<100; i++){
myCache.put(i,i);
for (int p : popular) {
myCache.get(p);
}
}
System.out.println(myCache.toString());
//{95=95, 96=96, 97=97, 98=98, 99=99, 1=1, 2=2, 3=3, 4=4, 5=5}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
963 次 |
| 最近记录: |