我需要从集合中获取一个数据(get()
调用,范围为100K,用于单个文件处理。)
public class DemoCollection {
private Map<GroupCriteria, GroupData> collectionHolder = new ConcurrentHashMap<GroupCriteria, GroupData>();
/**
*
* @param groupCriteria
* GroupCriteria
* @return GroupData
*/
public GroupData getGroupForGroupingCriteriaOne(GroupCriteria groupCriteria) {
GroupData groupData = null;
if (collectionHolder.containsKey(groupCriteria)) {
groupData = collectionHolder.get(groupCriteria);
} else {
// Get from database
}
return groupData;
}
/**
*
* @param groupCriteria
* GroupCriteria
* @return GroupData
*/
public GroupData getGroupForGroupingCriteriaTwo(GroupCriteria groupCriteria) {
GroupData groupData = null;
if ((groupData = collectionHolder.get(groupCriteria)) == null) {
// GEt from database
}
return groupData;
}
}
这方面的最佳做法是什么?方法一(getGroupForGroupingCriteriaOne
),两(getGroupForGroupingCriteriaTwo
)或两者都没有?
通常我会忽略这些过早优化的事情,但由于get()
调用过于庞大,我很少受到打扰。
你可以请一下建议吗?
答案 0 :(得分:2)
getGroupForGroupingCriteriaTwo是要走的路,因为你要求地图进行一次密钥查找而不是两次。
答案 1 :(得分:1)
getGroupForGroupingCriteriaTwo
看起来非常合理。 getGroupForGroupingCriteriaOne
对Map进行两次查找 - 一次用于搜索“key”,另一次用于获取值。
但是,我希望在fetching from database
之后,您可以将对象放入Map(作为缓存),以便下次可以使用Map,而不是查询。
答案 2 :(得分:1)
由于其他人指出的原因,第二版可能更好,但为什么不那么神秘......
public GroupData getGroupForGroupingCriteriaThree(GroupCriteria groupCriteria) {
GroupData groupData = collectionHolder.get(groupCriteria);
return groupData != null ? groupData : callGetDataFromDB();
}
答案 3 :(得分:1)
考虑使用Guava的MapMaker:
private ConcurrentMap<GroupCriteria, GroupData> collectionHolder = new MapMaker()
.makeComputingMap(
new Function<GroupCriteria, GroupData>() {
@Override
public GroupData apply(GroupCriteria key) {
//get from database and return
}
});
此ConcurrentMap
将为您处理所有并发请求。有关生成的地图的所有可配置功能的列表,请参阅MapMaker
文档。
答案 4 :(得分:1)
一般来说,我同意getGroupForGroupingCriteriaTwo
更好的回复,因为它只访问地图一次,但是你担心由于地图持有100K项目,访问时间会很高,这是错误的。
您正在使用ConcurrentHashMap,HashMap查找的计算复杂度为O(1)
,这意味着无论数据大小如何,这些调用都将在固定时间内返回。
此优化不会提高性能。如果您真的关心提高性能,请考虑使用适当的缓存框架。