我想在java中使用reflexion或introspection来替换“IF - ELSE”语句,我想知道那么昂贵的是“Reflexion”VS“IF - ELSE”语句吗?如果我使用aprox 700.000迭代进行循环,那么效率会更高吗?
答案 0 :(得分:1)
参见Effective Java,Item 53:首选接口到反射
性能受损。反射方法调用要慢得多 普通方法调用。 确切地说要慢多少,因为 工作中有很多因素。在我的机器上,速度差异可以是 小到两倍或大到五十倍。
答案 1 :(得分:0)
我找到this documentation,我了解风险
答案 2 :(得分:0)
正如您可能知道的那样,条件问题是它们削弱了处理器的可预测性特征。 这意味着如果错误,预取实际上会变成缺点。 当今天的处理器不知道比较的结果可能是什么时会发生这种情况,所以他们下注。 在IF-ELSE语句中,处理器有50%的概率正确预测下一条要执行的指令。 如果我们幸运的话,我们每个周期执行更多指令,如果不是,我们会得到一个约16个周期的中等惩罚,以便处理器从错误的预取中恢复。
那说让我们继续思考。
反思意味着,IF表现对您很重要。在大多数框架中,反射与地址调用是C_reflection = 3*C_address_call
。在Java中它更糟糕,我真的没有官方数据。最大的问题是名称/地址/可用性解析。
那说,让我们去现实世界,看看一些数字。我们现在可以理解,证明甚至预测结果。
我们测试了2个班级,3个考试。总共10M电话/测试|每班5M电话:
这些是以秒为单位的数字:
条件 - 0.022333
反思 - 3.02087
接口 - 0.012547
因此,在您的情况下,常见的接口是胜利者,其次是条件调用,几乎是执行时间的两倍(由于上面指定的原因)。最后一个带有极其显着差异的是反思。
以下是测试代码*:
import java.lang.reflect.InvocationTargetException;
public class JavaReflectionTest {
public interface ClassInterface {
public void execute();
public String getCount();
}
public static class ClassOne implements ClassInterface {
int count = 0;
public String getCount(){
return String.valueOf(count);
}
public void execute(){
count++;
}
}
public static class ClassTwo implements ClassInterface {
int count = 0;
public String getCount(){
return String.valueOf(count);
}
public void execute(){
count++;
}
}
public static void main(String[] args) throws SecurityException, NoSuchMethodException,
IllegalArgumentException, IllegalAccessException,
InvocationTargetException, ClassNotFoundException, InterruptedException {
ClassOne one = new ClassOne();
ClassTwo two = new ClassTwo();
ClassInterface ione = new ClassOne();
ClassInterface itwo = new ClassTwo();
long stopT;
long startT;
int i;
int mod;
//Warm up
for(i=0;i<350000;i++){
one.execute();
two.execute();
ione.execute();
itwo.execute();
one.getClass().getMethod("execute").invoke(one,null);
two.getClass().getMethod("execute").invoke(two,null);
}
//Test conditional call
one = new ClassOne();
two = new ClassTwo();
Thread.sleep(1000);
startT=System.nanoTime();
for(i=0;i<10000000;i++){
mod=i%2;
if(mod==0)
one.execute();
else
two.execute();
}
stopT=System.nanoTime();
System.out.println("Conditions - " + ((stopT-startT)/1000000000.0f)+ " Calls 1: " + one.getCount() + " Calls 2: " + two.getCount());
//Test reflection
one = new ClassOne();
two = new ClassTwo();
Thread.sleep(1000);
startT = System.nanoTime();
for(i=0;i<5000000;i++){
mod=i%2;
one.getClass().getMethod("execute").invoke(one,null);
two.getClass().getMethod("execute").invoke(two,null);
mod=i%2;
}
stopT=System.nanoTime();
System.out.println("Reflection - " + ((stopT-startT)/1000000000.0f)+ " Calls 1: " + one.getCount() + " Calls 2: " + two.getCount());
//Test common interface
ione = new ClassOne();
itwo = new ClassTwo();
Thread.sleep(1000);
startT = System.nanoTime();
for(i=0;i<5000000;i++){
mod=i%2;
ione.execute();
itwo.execute();
mod=i%2;
}
stopT=System.nanoTime();
System.out.println("Interface - " + ((stopT-startT)/1000000000.0f) + " Calls 1: " + ione.getCount() + " Calls 2: " + itwo.getCount());
}
}