我正在尝试从Hibernate中获取的约500万个对象加载到一个哈希映射表中,我为2种类型(A和B)执行此操作。我遍历POJO。Key是来自POJO的字段,值是POJO本身。
1.对于A类类型,键是整数字段。我可以在不到20秒的时间内加载地图。
对于B类
2.a)测试1,我的键是String字段。当我尝试将这些对象加载到新的哈希映射表中时(重新启动Java进程的新尝试,因此无需关心GC),需要约30秒才能将100K个对象加载到映射中。
2.b)测试2,当我尝试使用该类的另一个字段(整数类型)并加载映射时,它像第一个一样工作,并在不到20秒的时间内加载。
2.c)测试3,我想知道问题是否是数据类型。因此,对于类别B,我尝试了另一种方法,使用#2.b中的整数字段创建字符串键(key = int_field +“”),并且在<20秒钟内加载完成。
另一个测试,测试4,我针对类型B的测试是我创建密钥的方式。对于2.c,我像这样创建了密钥
map.put( pojo.getIntField() + "", pojo);
结果如2.c中所述
2.d)但是,当我在POJO中创建了另一个getter,返回int_field +“”并在map put中使用它时,
map.put( pojo.getIntFieldInStringForm(), pojo);
性能恶化到大约30秒,100K个对象。
我知道问题出在密钥上,因为我已经通过将结果对象添加到列表中来验证了db获取阶段,对于两种类型,它在<20秒内加载。
我无法理解其原因。如果有人能够请帮忙解释一下,这将非常有帮助。非常感谢。谢谢。
1.对于A类类型,键是整数字段。我可以在不到20秒的时间内加载地图。
对于B类
2.a)测试1,我的键是String字段。当我尝试将这些对象加载到新的哈希映射表中时(重新启动Java进程的新尝试,因此无需关心GC),需要约30秒才能将100K个对象加载到映射中。
2.b)测试2,当我尝试使用该类的另一个字段(整数类型)并加载映射时,它像第一个一样工作,并在不到20秒的时间内加载。
2.c)测试3,我想知道问题是否是数据类型。因此,对于类别B,我尝试了另一种方法,使用#2.b中的整数字段创建字符串键(key = int_field +“”),并且在<20秒钟内加载完成。
另一个测试,测试4,我针对类型B的测试是我创建密钥的方式。对于2.c,我像这样创建了密钥
map.put( pojo.getIntField() + "", pojo);
结果如2.c中所述
2.d)但是,当我在POJO中创建了另一个getter,返回int_field +“”并在map put中使用它时,
map.put( pojo.getIntFieldInStringForm(), pojo);
性能恶化到大约30秒,100K个对象。
我知道问题出在密钥上,因为我已经通过将结果对象添加到列表中来验证了db获取阶段,对于两种类型,它在<20秒内加载。
我无法理解其原因。如果有人能够请帮忙解释一下,这将非常有帮助。非常感谢。谢谢。
Map<String, ClassA> map = new HashMap<String, ClassA>();
Session session = sessionFactory.openNewSession();
try {
Iterator<ClassA> iterator = session.createQuery( "from ClassA" ).setFetchSize( 1000 ).iterate();
while ( iterator.hasNext() ) {
ClassB objClassA = iterator.next();
map.put( objClassB.getIntField(), objClassA );
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
session.close();
}
测试2.a
Map<String, ClassB> map = new HashMap<String, ClassB>();
Session session = sessionFactory.openNewSession();
try {
Iterator<ClassB> iterator = session.createQuery( "from ClassB" ).setFetchSize( 1000 ).iterate();
while ( iterator.hasNext() ) {
ClassB objClassB = iterator.next();
map.put( objClassB.getStringField(), objClassB );
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
session.close();
}
测试 #2.b
Map<Integer, ClassB> map = new HashMap<Integer, ClassB>();
Session session = sessionFactory.openNewSession();
try {
Iterator<ClassB> iterator = session.createQuery( "from ClassB" ).setFetchSize( 1000 ).iterate();
while ( iterator.hasNext() ) {
ClassB objClassB = iterator.next();
map.put( objClassB.getIntField(), objClassB );
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
session.close();
}
#2.c 测试
Map<String, ClassB> map = new HashMap<String, ClassB>();
Session session = sessionFactory.openNewSession();
try {
Iterator<ClassB> iterator = session.createQuery( "from ClassB" ).setFetchSize( 1000 ).iterate();
while ( iterator.hasNext() ) {
ClassB objClassB = iterator.next();
map.put( objClassB.getIntField() + "", objClassB );
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
session.close();
}
测试2.d
Map<String, ClassB> map = new HashMap<String, ClassB>();
Session session = sessionFactory.openNewSession();
try {
Iterator<ClassB> iterator = session.createQuery( "from ClassB" ).setFetchSize( 1000 ).iterate();
while ( iterator.hasNext() ) {
ClassB objClassB = iterator.next();
map.put( objClassB.getIntFieldInStringForm() + "", objClassB );
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
session.close();
}
getIntFieldInStringForm()
。我已经在问题中进行了更正。@Andreas 和 @Vince Emigh,我使用的字符串长度为8到10个字符。@Erwin,感谢您的意见,我会尽快发布示例代码以获得更清晰的理解。 - PKUobjClassB.getIntField() + ""
中的空字符串,并仅留下整数作为哈希键。通过向字段添加一些非空字符串来测试它,看看性能是否仍然保持在<20秒。从我所看到的情况来看,显而易见的罪魁祸首是字符串,需要为从数据库中提取的每个对象计算其哈希码。 - smac89