为了账号安全,请及时绑定邮箱和手机立即绑定

Java反射性能

Java反射性能

有只小跳蛙 2019-07-05 12:29:31
Java反射性能使用反射而不是调用类构造函数创建对象是否会导致显着的性能差异?
查看完整描述

3 回答

?
Helenr

TA贡献1780条经验 获得超4个赞

是的-当然。通过反射查找类是,按震级更贵。

引文Java反射文档:

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

在我的机器上运行SunJRE 6u10时,我在5分钟内完成了一个简单的测试:

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 reflection465 // using reflection

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

即使您只是实例化,您仍然得到了性能上的成功:

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

再说一次,YMMV。


查看完整回答
反对 回复 2019-07-05
?
12345678_0001

TA贡献1802条经验 获得超5个赞

是的,慢点。

但是记住第一条该死的规则-过早的优化是万恶之源。

(好吧,可能和1号绑在一起干)

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

在确定需要优化之前,千万不要进行优化,在此之前,只需编写好的、可读的代码即可。

我也不是说写愚蠢的代码。只要想一想最干净的方法,你就可以做到-没有复制和粘贴,等等。(仍然要小心内部循环和使用最适合您需要的集合-忽略这些不是“未优化的”编程,而是“糟糕的”编程)

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

编辑:

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

上课?永远不要优化,直到你写了一个干净的,整洁的编码解决方案,并证明它是太慢。


查看完整回答
反对 回复 2019-07-05
?
喵喵时光机

TA贡献1846条经验 获得超7个赞

您可能会发现,JVM正在优化A=新的A()。如果将对象放入数组中,则它们的性能不太好。)以下指纹.

new A(), 141 ns
A.class.newInstance(), 266 nsnew A(), 103 ns
A.class.newInstance(), 261 nspublic class Run {
    private static final int RUNS = 3000000;

    public static class A {
    }

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

    public static void doRegular() throws Exception {
        A[] as = new A[RUNS];
        long start = System.nanoTime();
        for (int i = 0; i < RUNS; i++) {
            as[i] = new A();
        }
        System.out.printf("new A(), %,d ns%n", (System.nanoTime() - start)/RUNS);
    }

    public static void doReflection() throws Exception {
        A[] as = new A[RUNS];
        long start = System.nanoTime();
        for (int i = 0; i < RUNS; i++) {
            as[i] = A.class.newInstance();
        }
        System.out.printf("A.class.newInstance(), %,d ns%n", (System.nanoTime() - start)/RUNS);
    }}

这表明我的机器上的差别大约是150 ns。


查看完整回答
反对 回复 2019-07-05
  • 3 回答
  • 0 关注
  • 493 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信