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的数组
- 检查数组的长度,以及
- 将数组中的参数从
强制转换为相应的参数类型对象
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