java - 反射获取的方法的执行时间是否更长?

标签 java performance reflection

众所周知,可以使用 Reflection 获取方法并通过返回的 Method 实例调用它。

但是我的问题是;一旦它被 Reflection 获取并且我一遍又一遍地调用 Method ,该方法的性能是否会比调用方法的正常方式慢?

例如:

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();
        }
    }
}

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

最佳答案

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

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);
}

我还将 test 移动到 static 字段,以便它可以编译和运行

private static Method test;
static {
    try {
        test = ReflectionTest.class.getMethod("testMethod");
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    }
}

我得到了相当一致的差异(或一致的输出)

4526 606

这表明在 10000 调用中,反射比直接调用慢约 7 倍。

关于java - 反射获取的方法的执行时间是否更长?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27894609/

相关文章:

java - hibernate 无法获得正确的结果集

java - AWS Lambda + SQS(Java)。 Lambda 成功完成工作,但未从 SQS 中删除消息。是否应该再次发送此消息进行处理?

javascript - Ionic App 在移动浏览器中运行流畅

php - 什么是最快的?循环内部或外部的条件?

java - 设计模式问题

java - 使用java反射获取代理表示的对象

c# - 使用 AutoMapper 对字符串的枚举描述

java - 可调用和泛型的集合

java - 如何计算从控制台读取的整数序列的平均值?

c# - 第一轮和第二轮速度差