无论在类中提供访问器是一个好的还是坏的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));
}
}
}
结果如下:
谢谢大家。
答案 0 :(得分:3)
在典型的机器上,通过反射调用吸气剂的成本约为3 ns。二传手大致相同。由于吸气剂可以内联甚至消除而没有反射,因此存在较高的相对差异。
3 ns会给你多少差异?
我提供了一个代码示例,并在昨天回答HERE。 ;)
答案 1 :(得分:2)
为了获得其他人所讨论的最低性能,请务必了解这涉及仅对现有Method
对象的反射调用。如果您在每次通话中都进行查询,则效果匹配为巨大。
答案 2 :(得分:0)
我认为thread会回答您关于整体表现的问题。希望这个blog能帮助您获得一些信息。关于基准价值。它有一些外部链接,例如来自IBM的帖子 - Reflection performance benchmark。讨论基准值。
答案 3 :(得分:0)
它比以前更好(我认为在1.4之前),但仍然比直接访问变量慢。我相信这是因为必须将类和所有属性加载到内存中,然后在列表中搜索所需的属性。
在进行Android开发以切断虚拟方法调用时,Google建议(或至少是)直接访问变量。