Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 反射获取的方法的执行是否需要更长的时间?_Java_Performance_Reflection - Fatal编程技术网

Java 反射获取的方法的执行是否需要更长的时间?

Java 反射获取的方法的执行是否需要更长的时间?,java,performance,reflection,Java,Performance,Reflection,大家都知道,可以通过反射获取一个方法,并通过返回的方法实例调用它 但我的问题是,;一旦通过反射获取,并且我反复调用方法,该方法的性能会比调用方法的正常方式慢吗 例如: import java.lang.reflect.Method; public class ReflectionTest { private static Method test; public ReflectionTest() throws Exception { test = this.g

大家都知道,可以通过
反射
获取一个方法,并通过返回的
方法
实例调用它

但我的问题是,;一旦通过
反射
获取,并且我反复调用
方法
,该方法的性能会比调用方法的正常方式慢吗

例如:

import java.lang.reflect.Method;

public class ReflectionTest {

    private static Method test;

    public ReflectionTest() throws Exception {
        test = this.getClass().getMethod("testMethod", null);
    }

    public void testMethod() {
        //execute code here
    }

    public static void main(String[] args) throws Exception {
        ReflectionTest rt = new ReflectionTest();
        for (int i = 0; i < 1000; i++) {
            rt.test.invoke(null, null);
        }

        for (int i = 0; i < 1000; i++) {
            rt.testMethod();
        }
    }
}
import java.lang.reflect.Method;
公共类反射测试{
专用静态法试验;
public ReflectionTest()引发异常{
test=this.getClass().getMethod(“testMethod”,null);
}
公共void testMethod(){
//在这里执行代码
}
公共静态void main(字符串[]args)引发异常{
ReflectionTest rt=新的ReflectionTest();
对于(int i=0;i<1000;i++){
rt.test.invoke(null,null);
}
对于(int i=0;i<1000;i++){
rt.testMethod();
}
}
}

我这样问是因为我正在创建一个事件系统,在注册侦听器时,它会扫描注释。这些方法被放入映射中,然后在每次发生其所需参数类型的事件时执行。例如,我不知道这是否足够用于游戏。

使用无反射的方法大约快一个数量级。我试了一下

public static void main(String[] args) throws Exception {
    ReflectionTest rt = new ReflectionTest();
    // Warm up
    for (int i = 0; i < 100; i++) {
        test.invoke(rt, null);
    }
    for (int i = 0; i < 100; i++) {
        rt.testMethod();
    }

    long start = System.nanoTime();
    for (int i = 0; i < 10000; i++) {
        test.invoke(rt, null);
    }
    long end = Math.abs((start - System.nanoTime()) / 1000);
    start = System.nanoTime();
    for (int i = 0; i < 10000; i++) {
        rt.testMethod();
    }
    long end2 = Math.abs((start - System.nanoTime()) / 1000);
    System.out.printf("%d %d%n", end, end2);
}
我得到了相当一致的差异(或输出一致)


这表明跨
10000
调用的反射比直接调用慢约7倍。

@Elliot Frisch的回答提供了确凿的证据,证明使用
方法.invoke()
的速度较慢

无论如何,你都会想到这一点,因为反射版本需要额外的工作;e、 g

  • 创建和初始化包含varags的数组
  • 检查数组的长度,以及
  • 将数组中的参数从
    对象
    强制转换为相应的参数类型
在某些情况下,JIT可能会对此进行优化



1-好的。。。无定论的基准测试是有问题的,因为它没有适当注意处理可能的JVM预热异常。

可能没有执行,也许在抓取方面?我相信如果我注意抓取的数量,它不会对性能产生太大的影响?让我们等待专业人士的回答:你可以自己分析它吗?因为另一个问题是询问不同的反射方式的性能,这是关于反射和纯调用的问题。我引述:“然而,我的问题是,一旦它被反射获取,并且我反复调用该方法,该方法的性能会比调用方法的正常方式慢吗?”嗯。这令人失望:(.我真的很喜欢我的事件系统的工作方式。同样的测试在我的电脑上进行了
1740 228
。你认为我应该保持事件系统的原样,还是你对更好的事件系统有什么建议?老实说,我认为这可能是过早优化的情况。反射给你的额外灵活性似乎很好这是惩罚,如果有一些关键路径,那么当你找到它时,你可以对其进行优化。@Limnic-你希望有人如何回答这个问题……除非他们看到了你的事件系统的代码?是的,“过早优化”!!在查看了我的问题评论中提供的相关问题后,我使用了
MethodHandle
而不是
Method
,这产生了更好的结果:
850 239
@StephenC我想我只是在寻找一个意见,基于反射的事件系统是否适用于性能重要的应用程序。您还可以检查Java 8风格的
函数。应用
使用者。接受
以比较新实现的功能的性能
private static Method test;
static {
    try {
        test = ReflectionTest.class.getMethod("testMethod");
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    }
}
4526 606