我面临一个问题。现在,我看到我们的旧代码有一个批处理插入。在此之前,该代码进行了大量验证。但是,我认为可以改进的一件事是在遗留代码中,每次我们尝试从DB加载数据并查看其是否存在时。我以为可以在第一时间(第一项)将所有表数据加载到并发的哈希图中,但是只需检查映射中的记录即可。这是代码。
private ConcurrentMap<String, Integer> name2IdMap;
........
public Integer fetchIdByName(String name) {
if (name2IdMap == null) {
List<Entity> entities = dao.listAll();
Map<String, Integer> temp = entities.stream().collect(Collectors.toMap(Entity::getName, Entity::getId));
name2IdMap = new ConcurrentHashMap<>(temp);
}
return name2IdMap.get(name);
}
但是,当我尝试插入5000行时,我注意到缓存方式太慢了,我认为它应该快得多。有人可以对此发表评论吗?谢谢
更新:我记录了时间并进行了检查。该地图确实生效。更具体地说,第一次(加载到地图)需要更多时间。但是之后,它需要0毫秒才能找到ID。当我们有更多数据时,这确实提高了性能。但是,问题出在我从缓存中获得了这个经过验证的值之后,当我尝试稍后再从数据库中获取另一个对象(相同的代码)时,它花费的时间要长得多(从之前的12毫秒到现在的7秒钟)。变慢的代码是
public List<M> findByExample(M instance) {
Criteria crit = getSession().createCriteria(getClass());
Example example = Example.create(instance);
crit.add(example);
List<M> list = crit.list();
return list;
}
通过日志记录,唯一的步骤是太多的时间是list(),我不知道为什么。导致以前从map或db获取值的方式似乎与此代码无关。我正在使用mysql。现在,我在考虑是否有一些事情,例如您不经常获取数据库(毫秒级别)时,他们会将其置于“睡眠”模式。
答案 0 :(得分:0)
一些潜在原因,
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html