如何加速反射代码



在我的应用程序中,我使用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;
 }

可能是build &缓存行映射逻辑,这样你就不必扫描字段、注释、结果集元数据&

JDBC元数据访问特别慢。

在这个例子中,您可以提供一个字符串'key'来为不同的结果集类型(不同的列结构)高效地缓存映射器。

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'语句。只需调用Field.set(),使用ResultSet.getObject()作为参数。所有正确的事情都会在内部发生。但我不是说这会更快。

你最好使用java的反射功能。

相关内容

  • 没有找到相关文章

最新更新