这是我试图解决的用例的示例问题。 在数据库中有一个表格,它在两个地方之间旅行时每天消耗的时间,这个表格中等,即有5万个条目。所以我们想在这个表周围缓存以减少数据库负载。因此,问题陈述是返回在特定日期到达地点X和Y之间的时间。
同样的查询可以多次执行,因此我们需要在实施解决方案时留出空间。
下面是我的实现我删除了从DB中获取数据以删除混乱的代码。为简化起见,您可以假设该表有4列 Travelled_date,from,to,Time_taken。
缓存有两个暴露给最终用户的方法来获取时间,当用户从/到/和日期获取时间时,我当前实现中存在问题。在这里我每次创建TravelledPlaces的对象,我做了不可变但但后来用相同的参数调用缓存将创建多个TravelledPlaces对象,这会占用主内存。是否有任何建议可以避免同一次调用此对象的多次创建?
以下是代码
public class TimeConsumedCache {
private Map<Date, Map<TravelledPlaces, Double>> timeCache = new HashMap<Date, Map<TravelledPlaces, Double>>();
public double getTimeTravelled(Date date, TravelledPlaces tp) {
return timeCache.get(date).get(tp);
}
public double getTimeTravelled(Date date, String from, String to) {
return timeCache.get(date).get(new TravelledPlaces(from, to));
}
private static final class TravelledPlaces {
private String fromLocation;
private String toLocation;
public TravelledPlaces(String fromLocation, String toLocation) {
this.fromLocation = fromLocation;
this.toLocation = toLocation;
}
//hashcode and equals removed for brevity
}
}
如果我直接使用
怎么样 timeCache.get(date).get(from + to)); and change cache definition to
Map<Date, Map<String, Double>> but this loses the object oriented approach of dealing with the problem
答案 0 :(得分:1)
每次创建我制作的TravelledPlaces对象 不可变但后续调用具有相同参数的缓存 创建多个TravelledPlaces对象,这将耗尽主内存
这是一个不正确的假设。
return timeCache.get(date).get(new TravelledPlaces(from, to));
不会吃掉记忆。用于查询的对象将被垃圾收集。我可以假设一个不错的优化,内存开销将接近一个对象的大小。
一个问题可能来自timeCache
的大小。连续添加从零到50k的元素将需要增加容器容量。
如果以惰性方式构建缓存,只有在缺少元素时才添加元素,这些成本将被分摊。如果由于任何原因你必须预先构建整个缓存,那么我建议只使用一个地图和
class DatedTravelledPlaces
{
private Date date;
private TravelledPlaces places;
DatedTravelledPlaces(Date date, String from, String to)
{
//construction
}
@Override
public int hashCode() {
//same as what you did with TravelledPlaces
}
@Override
public boolean equals(Object obj) {
//same as what you did with TravelledPlaces
}
}
public class TimeConsumedCache {
private Map<DatedTravelledPlaces, double> timeCache;
TimeConsumedCache()
{
int dbsize = computeDBSize();
timeCache = new HashMap<DatedTravelledPlaces, double>(dbsize );
}
}