[英]How to speed up Reflection Code?
在我的应用程序中,我使用Apache的DBUtils类从MySQL数据库读取。 我编写了一个自定义BasicRowProcessor,它在数据对象的字段上使用批注来从数据库中读取列。 它在代码方面确实工作得很好,但是当我拉很多行时,性能却很慢。 例如,使用此代码,一个1500行x 35列的结果集将花费800ms,但是如果我使用的是标准JDBC代码,则只需要80ms。
问题-我可以怎样加快此代码的速度? 具体来说,我使用了很多反射和注释-是否缺少技巧来加快速度?
@Override
public <T> T toBean(ResultSet rs, Class<T> type) throws SQLException
{
T data = type.newInstance();
Field[] f = type.getFields();
for (int i=0; i<f.length; i++)
{
Field field = f[i];
if (field.isAnnotationPresent(DBColumn.class))
{
String columnName = field.getAnnotation(DBColumn.class).name();
}
if (field.getType().getName().equals("int"))
{
field.setInt(data, rs.getInt(columnName));
}
else if (field.getType().getName().equals("long"))
{
field.setLong(data, rs.getLong(columnName));
}
// .... for all the other types
}
return data;
}
也许可以构建并缓存行映射逻辑,因此您不必每次都扫描字段,注释,结果集元数据和类型。
JDBC元数据访问特别慢。
在此示例中,您可以提供字符串“键”,以针对不同的结果集类型(不同的列结构)启用映射器的高效缓存。
public BasicRowProcessor getReflectiveRowMapper (ResultSet rs, String resultSetKey, Class<T> type) {
String key = resultSetKey+"-"+type;
BasicRowProcessor result = rrmCache.get( key);
if (result != null) {
result = buildReflectiveRowMapper (rs, resultSetKey, type);
rrmCache.put( key, result);
}
return result;
}
public BuiltRowProcessor buildReflectiveRowMapper (ResultSet rs, String resultSetKey, Class<T> type) {
}
然后..
public class BuiltRowProcessor extends BasicRowProcessor {
protected FieldMapping[] mappings;
@Override
public <T> T toBean (ResultSet rs, Class<T> type) throws SQLException {
T data = type.newInstance();
for (FieldMapping field : mappings) {
field.mapField( rs, data);
}
return data;
}
}
abstract public class FieldMapping {
protected Field field;
protected int columnIndex;
// constructor..
abstract public void mapField (ResultSet rs, Object target) throws SQLException;
protected void writeField (Object target, Object value) {
try {
field.setValue(target, value); // or whatever API.
} catch (Exception x) {
throw new RuntimeException("error writing field: "+field, x);
}
}
}
public IntMapping extends FieldMapping {
// constructor..
public void mapField (ResultSet rs, Object target) throws SQLException {
int value = rs.getInt(columnIndex);
writeField( target, value);
}
}
不要比较类型的名称。 比较类型,以int.class,long.class等。
实际上,您不需要所有这些“ if”语句。 只需使用ResultSet.getObject()作为参数调用Field.set()。 正确的事情将在内部发生。 但是我没有说这会更快。
使用java.beans Introspector的反射功能会更好,因为它会为您缓存所有反射内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.