反射比平常慢得多

时间:2013-12-02 21:21:15

标签: java reflection jvm weblogic weblogic11g

我目前正在开发一个Java项目,我正在努力学习这些项目。在以前的项目中,我使用Java反射来创建一个toString(),方法是调用一个对象中的每个getter并解析它以显示该值。这种方法是一种有用,干净,动态的显示数据的方法。

以下是我的代码的大幅简化版本:

private static String objectToString(Object o) {
    LOGGER.debug("entering ObjectStringUtils::objectToString()");


    ....

    Class<?> oClass = o.getClass();
    String className = oClass.getName();
    Method[] methods = oClass.getMethods();

    for (Method m : methods) {
         if ([method is a getter]) {
               String methodName;
               Object value;
               try {
                   methodName= m.getName();
                   LOGGER.debug("Invoking " + className + "::" + methodName);
                   Object value = m.invoke(o);
                   LOGGER.debug("Invoked " + className + "::" + methodName);
               } catch (Exception e) {
                   e.printStackTrace();
                   value = null;
               }

               LOGGER.debug(methodName+ " -> " + value);
         }
    }
}

这会产生如下所示的记录器输出:

14:47:49,478 [] DEBUG ObjectStringUtils:? - Invoking org.hibernate.impl.SessionImpl::isOpen
14:47:49,613 [] DEBUG ObjectStringUtils:? - Invoked org.hibernate.impl.SessionImpl::isOpen
14:47:49,613 [] DEBUG ObjectStringUtils:? - isOpen -> true

请注意,调用该函数需要Java 139毫秒在任何类中的任何方法中执行反射都需要很长时间,即使该方法只是一个标准的getter,除了返回值之外不执行任何逻辑。这意味着它需要太长时间在涉及多个嵌套值时执行操作。当我之前在WebSphere 7上使用反射时,只花了这么长的时间来执行操作。

所以我的问题是:为什么处理这么长时间?我知道反射速度较慢,但​​调用吸气剂的时间不应超过140毫秒。这是WebLogic长时间调用函数的方式,还是行号似乎从.class文件中剥离的事实?到目前为止,我没有任何想法。

2 个答案:

答案 0 :(得分:1)

当您对一段代码进行基准测试时,您必须多次对进行相同的操作,否则测试毫无意义 - 它可能是由垃圾收集或在同一台计算机上运行的其他进程引起的

答案 1 :(得分:0)

缓存Method时 - 例如在框架中使用oClass.getMethods()只调用一次,对方法的反射调用比直接方法调用慢〜2-3。我认为oClass.getMethods()必须是反射中最慢的部分,而不是方法调用。

所以可能是SessionImpl::isOpen本身很慢?即它检查它是否仍然连接,或与数据库的任何缓慢交互?即使对于数据库事务,139 ms也非常慢,因此也可能因为在此调用期间发生一些错误而发生这种情况。