我有一个代价高昂的函数,它将各种double
变量作为输入:
public double f(double v1, double v2, double v3){
...
return output;
}
所以我尝试使用两种不同的策略记住它的输出。
Map<Double,Map<Double,Map<Double,Double>>> map = new HashMap<>();
public double f(double v1, double v2, double v3){
// This is abbreviated: in my case I made sure to call only once each "get()"
if(map.containsKey(v1) && map.get(v1).containsKey(v2) && map.get(v1).get(v2).containsKey(v3))
return map.get(v1).get(v2).get(v3);
...
// calculations
...
// put "output" in the map (and create new intermediate HashMaps when needed)
...
return output;
}
public class DoubleKey {
public final double[] values;
public DoubleKey(double[] values){ this.values = values;}
@Override
public boolean equals(Object key){
if(key instanceof DoubleKey)
return Arrays.equals(values, ((DoubleKey)key).values);
return false;
}
@Override
public int hashcode(){
return Arrays.hashcode(values);
}
}
Map<DoubleKey,Double> map = new HashMap<>();
public double f(double v1, double v2, double v3){
DoubleKey key = new DoubleKey(new double[]{v1,v2,v3});
if(map.containsKey(key))
return map.get(key);
...
// calculations
...
map.put(key, output);
return output;
}
现在,我希望第二种方法更快,因为它使用单个Hashmap,并且感觉通常更优雅。但事实证明,与第一种提高速度的方法相比,我从第二种方法中获得的收益较少。
你知道为什么第二种方法的效率会降低吗?是使用Arrays.equals()
和/或Arrays.hashcode()
的费用吗?
更一般地说,你知道其他更有效的记忆技术吗?