如果我实现一个java类,那么性能会下降多少?使用反射的访问者?

时间:2013-01-04 16:31:05

标签: java reflection

无论在类中提供访问器是一个好的还是坏的OO实践,我想知道通过反射执行对对象的特定属性的访问是否会降低性能(内存消耗或CPU时间)。

您是否实施了这项并执行了基准测试? 你知道有谁做过这样的基准吗?

编辑:

由于一些评论表明性能下降明显,我修改了问题的标题,表明我想知道用反射实现访问器的影响有多糟糕

编辑:

感谢您的好意见和答案。根据@Peter Lawrey的回答和@EJP的评论,这就是我的意思,想知道你们是否有人在我的问题之前实施过:

package co.com.prueba.reflection;

import java.lang.reflect.Field;

public class A {

private String s;


public void setS(String s){
    this.s=s;
}

public String getS(){
    return this.s;
}

public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {

    System.out.println("Invoking .setAccesible(true) ...");
    A secondA = new A();
    for(int i=0; i<10; i++){
        long start = System.nanoTime();
        Field f = secondA.getClass().getDeclaredField("s");
        f.setAccessible(true);
        f.get(secondA);
        long end = System.nanoTime();
        System.out.println((end - start));
    }

    System.out.println("Without invoking .setAccesible(true) ...");
    A firstA = new A();     
    for(int i=0; i<10; i++){
        long start = System.nanoTime();
        Field f = firstA.getClass().getDeclaredField("s");          
        f.get(firstA);
        long end = System.nanoTime();
        System.out.println((end - start));
    }

    System.out.println("Invoking the getter ...");
    A thirdA = new A();
    for(int i=0; i<10; i++){
        long start = System.nanoTime();
        thirdA.getS();
        long end = System.nanoTime();
        System.out.println((end - start));
    }


}

}

结果如下:

enter image description here

谢谢大家。

4 个答案:

答案 0 :(得分:3)

在典型的机器上,通过反射调用吸气剂的成本约为3 ns。二传手大致相同。由于吸气剂可以内联甚至消除而没有反射,因此存在较高的相对差异。

3 ns会给你多少差异?

我提供了一个代码示例,并在昨天回答HERE。 ;)

答案 1 :(得分:2)

为了获得其他人所讨论的最低性能,请务必了解这涉及对现有Method对象的反射调用。如果您在每次通话中都进行查询,则效果匹配为巨大

答案 2 :(得分:0)

我认为thread会回答您关于整体表现的问题。希望这个blog能帮助您获得一些信息。关于基准价值。它有一些外部链接,例如来自IBM的帖子 - Reflection performance benchmark。讨论基准值。

答案 3 :(得分:0)

Java Reflection Performance

它比以前更好(我认为在1.4之前),但仍然比直接访问变量慢。我相信这是因为必须将类和所有属性加载到内存中,然后在列表中搜索所需的属性。

在进行Android开发以切断虚拟方法调用时,Google建议(或至少是)直接访问变量。