Java 反射性能

2022-08-31 06:22:29

使用反射而不是调用类构造函数创建对象是否会导致任何显著的性能差异?


答案 1

是的 - 绝对可以。通过反射查找类,按数量级计算,成本更高。

引用Java关于反思的文档

由于反射涉及动态解析的类型,因此无法执行某些 Java 虚拟机优化。因此,反射操作的性能低于非反射操作,因此在性能敏感型应用程序中经常调用的代码节中应避免使用反射操作。

以下是我在5分钟内在我的机器上运行Sun JRE 6u10的简单测试:

public class Main {

    public static void main(String[] args) throws Exception
    {
        doRegular();
        doReflection();
    }

    public static void doRegular() throws Exception
    {
        long start = System.currentTimeMillis();
        for (int i=0; i<1000000; i++)
        {
            A a = new A();
            a.doSomeThing();
        }
        System.out.println(System.currentTimeMillis() - start);
    }

    public static void doReflection() throws Exception
    {
        long start = System.currentTimeMillis();
        for (int i=0; i<1000000; i++)
        {
            A a = (A) Class.forName("misc.A").newInstance();
            a.doSomeThing();
        }
        System.out.println(System.currentTimeMillis() - start);
    }
}

有了这些结果:

35 // no reflection
465 // using reflection

请记住,查找和实例化是一起完成的,在某些情况下,查找可以重构掉,但这只是一个基本示例。

即使您只是实例化,您仍然会受到性能影响:

30 // no reflection
47 // reflection using one lookup, only instantiating

再次,YMMV。


答案 2

是的,它更慢。

但请记住该死的#1规则 - 过早的优化是万恶之源

(好吧,可能与DRY的#1并列)

我发誓,如果有人在工作中来找我并问我这个问题,在接下来的几个月里,我会非常注意他们的代码。

在你确定需要它之前,你永远不能优化,在那之前,只要写出好的、可读的代码。

哦,我也不是说写愚蠢的代码。只要想想你可以做的最干净的方式 - 没有复制和粘贴等(仍然要警惕像内部循环这样的东西,并使用最适合你需求的集合 - 忽略这些不是“未优化”的编程,而是“坏”编程)

当我听到这样的问题时,我吓坏了,但后来我忘记了每个人都必须自己学习所有规则才能真正理解它。在你花了一个人月的时间调试某人“优化”的东西之后,你会得到它。

编辑:

在这个线程中发生了一件有趣的事情。检查#1答案,这是编译器在优化方面有多强大的一个例子。该测试完全无效,因为非反射实例化可以完全分解。

课?在你写出一个干净、编码整齐的解决方案并证明它太慢之前,不要进行任何优化。


推荐